summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--algorithm.mod/algorithm.bmx645
-rw-r--r--bitmapfont.mod/bitmapfont.bmx438
-rw-r--r--gfxmenu.mod/gfxmenu.bmx412
-rw-r--r--keysyms.mod/keysyms.bmx366
-rw-r--r--mwidget.mod/mwidget.bmx5615
-rw-r--r--showlicense.mod/showlicense.bmx399
-rw-r--r--simplegui.mod/simplegui.bmx1
-rw-r--r--vector.mod/vector.bmx397
-rw-r--r--vectorgfx.mod/vectorgfx.bmx1365
-rw-r--r--win32.mod/win32.bmx224
10 files changed, 4923 insertions, 4939 deletions
diff --git a/algorithm.mod/algorithm.bmx b/algorithm.mod/algorithm.bmx
index 065a254..c449f5f 100644
--- a/algorithm.mod/algorithm.bmx
+++ b/algorithm.mod/algorithm.bmx
@@ -1,323 +1,322 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.algorithm
-EndRem
-Module noddybox.algorithm
-
-ModuleInfo "Framework: Various algorithm routines"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-Import brl.math
-Import brl.linkedlist
-
-Rem
-bbdoc: Used to return integer points from algorithms.
-EndRem
-Type TAlgoPoint
- Rem
- bbdoc: The X co-ordinate of the point
- EndRem
- Field x:Int
- Rem
- bbdoc: The Y co-ordinate of the point
- EndRem
- Field y:Int
-
- Rem
- bbdoc: Create a point.
- returns: Newly created point.
- about: @x and @y are initialised with the passed parameters.
- EndRem
- Function Create:TAlgoPoint(x:Int, y:Int)
- Local o:TAlgoPoint=New TAlgoPoint
- o.x=x
- o.y=y
- Return o
- End Function
-
-End Type
-
-Rem
-bbdoc: Used to return double points from algorithms.
-EndRem
-Type TAlgoPointD
- Rem
- bbdoc: The X co-ordinate of the point
- EndRem
- Field x:Double
- Rem
- bbdoc: The Y co-ordinate of the point
- EndRem
- Field y:Double
-
- Rem
- bbdoc: Create a point.
- returns: Newly created point.
- about: @x and @y are initialised with the passed parameters.
- EndRem
- Function Create:TAlgoPointD(x:Double, y:Double)
- Local o:TAlgoPointD=New TAlgoPointD
- o.x=x
- o.y=y
- Return o
- End Function
-
-End Type
-
-Rem
-bbdoc: Used to return 3D points from algorithms.
-EndRem
-Type TAlgoPoint3D
- Rem
- bbdoc: The X co-ordinate of the point
- EndRem
- Field x:Double
- Rem
- bbdoc: The Y co-ordinate of the point
- EndRem
- Field y:Double
- Rem
- bbdoc: The Z co-ordinate of the point
- EndRem
- Field z:Double
-
- Rem
- bbdoc: Create a point.
- returns: Newly created point.
- about: @x, @y and @z are initialised with the passed parameters.
- EndRem
- Function Create:TAlgoPoint3D(x:Double, y:Double, z:Double)
- Local o:TAlgoPoint3D=New TAlgoPoint3D
- o.x=x
- o.y=y
- o.z=z
- Return o
- End Function
-
-End Type
-
-Rem
-bbdoc: Rotates a point.
-returns: The rotated point.
-about: @x, @y are rotated around 0,0 by @angle, which is the value in degrees multiplied by ten.
-about: To speed things up a simple 3600 element lookup table is used, so @angle <u>must</u> be 0 to 3599 inclusive, or a runtime error will result.
-EndRem
-Function DoRotate:TAlgoPoint(x:Int, y:Int, angle:Int)
- AlgoStatic.Init()
-
- Local dx:Double=x
- Local dy:Double=y
- Local dco:Double=AlgoStatic.co[angle]
- Local dsi:Double=algoStatic.si[angle]
-
- Return TAlgoPoint.Create(dco*dx+(-dsi)*dy,dsi*dx+dco*dy)
-End Function
-
-Rem
-bbdoc: Rotates a point (double version)
-returns: The rotated point.
-about: @x, @y are rotated around 0,0 by @angle, which is the value in degrees multiplied by ten.
-about: To speed things up a simple 3600 element lookup table is used, so @angle <u>must</u> be 0 to 3599 inclusive, or a runtime error will result.
-EndRem
-Function DoRotateD:TAlgoPointD(x:Double, y:Double, angle:Int)
- AlgoStatic.Init()
-
- Local dco:Double=AlgoStatic.co[angle]
- Local dsi:Double=algoStatic.si[angle]
-
- Return TAlgoPointD.Create(dco*x+(-dsi)*y,dsi*x+dco*y)
-End Function
-
-Rem
-bbdoc: Implements a Bresenham style line.
-returns: A list of points making up the line.
-about: @px1, @py1, @px2 and @py2 are the end points of the line.
-EndRem
-Function DoLine:TList(p1x:Int, p1y:Int, p2x:Int, p2y:Int)
- Local list:TList=CreateList()
- Local f:Int
- Local dx:Int
- Local dy:Int
- Local ix:Int
- Local iy:Int
- Local incrE:Int
- Local incrNE:Int
- Local d:Int
- Local x:Int
- Local y:Int
- Local ymode:Int
-
- dx=p2x-p1x
- dy=p2y-p1y
-
- ix=Sgn(dx)
- iy=Sgn(dy)
-
- dx=Abs(dx)
- dy=Abs(dy)
-
- If dy>dx
- ymode=True
- d=dx*2-dy
- incrE=dx*2
- incrNE=(dx-dy)*2
- Else
- ymode=False
- d=dy*2-dx
- incrE=dy*2
- incrNE=(dy-dx)*2
- EndIf
-
- x=p1x
- y=p1y
-
- list.AddLast(TAlgoPoint.Create(x,y))
-
- If ymode
- While y<>p2y
- If d<=0
- d:+incrE
- y:+iy
- Else
- d:+incrNE
- y:+iy
- x:+ix
- EndIf
-
- list.AddLast(TAlgoPoint.Create(x,y))
- Wend
- Else
- While x<>p2x
- If d<=0
- d:+incrE
- x:+ix
- Else
- d:+incrNE
- y:+iy
- x:+ix
- EndIf
-
- list.AddLast(TAlgoPoint.Create(x,y))
- Wend
- EndIf
-
- Return list
-End Function
-
-
-Rem
-bbdoc: Returns the points for degrees 0-359 on the described circle.
-returns: A list of points making up the circle.
-about: @x, @y is the centre of the circle, @r it's radius.
-EndRem
-Function DoCircle:TAlgoPoint[](x:Int, y:Int, r:Int)
- Local p:TAlgoPoint[]=New TAlgoPoint[360]
- Local f:Int
-
- AlgoStatic.Init()
-
- For f=0 To 359
- p[f]=TAlgoPoint.Create(x+r*AlgoStatic.si[f*10],y+r*AlgoStatic.co[f*10])
- Next
-
- Return p
-End Function
-
-
-Rem
-bbdoc: Returns the points where a sphere intersects a 3D line.
-returns: null if they don't intersect, one point if it intersects as a tangent, two points otherwise.
-about: @x1, @y1, @z1, @x2, @y2 and @z2 describe the line. @cx, @cy, @cz and @rad describe the sphere.
-about: Leave the Z co-ords as zero to do a 2D check.
-EndRem
-Function CircleIntersects:TAlgoPoint3D[](x1:Double, y1:Double, z1:Double, x2:Double, y2:Double, z2:Double, cx:Double, cy:Double, cz:Double, rad:Double)
- Local a:Double = Square(x2-x1) + Square(y2-y1) + Square(z2-z1)
- Local b:Double = 2 * ( (x2-x1)*(x1-cx) + (y2-y1)*(y1-cy) + (z2-z1)*(z1-cz) )
- Local c:Double = Square(x1) + Square(y1) + Square(z1) + Square(cx) + Square(cy) + Square(cz) - 2 * ( cx*x1 + cy*y1 + cz*z1 ) - Square(rad)
- Local i:Double = b*b-4*a*c
-
- If i<0
- Return Null
- ElseIf i=1.0
- Local m:Double = -b/(2*a)
- If m<0.0 Or m>1.0
- Return Null
- EndIf
- Local p:TAlgoPoint3D[]=New TAlgoPoint3D[1]
- p[0]=TAlgoPoint3D.Create( x1+m*(x2-x1), y1+m*(y2-y1), z1 + m*(z2-z1))
- Return p
- Else
- Local e:Double = Sqr(Square(b) - 4*a*c)
- Local m1:Double = (-b + e) / (2*a)
- Local m2:Double = (-b - e) / (2*a)
-
- If (m2<0.0 Or m2>1.0) And (m1<0.0 Or m1>1.0)
- Return Null
- ElseIf (m1<0.0 Or m1>1.0)
- Local p:TAlgoPoint3D[]=New TAlgoPoint3D[1]
- p[0]=TAlgoPoint3D.Create( x1+m2*(x2-x1), y1+m2*(y2-y1), z1+m2*(z2-z1))
- Return p
- ElseIf m2<0.0 Or m2>1.0
- Local p:TAlgoPoint3D[]=New TAlgoPoint3D[1]
- p[0]=TAlgoPoint3D.Create( x1+m1*(x2-x1), y1+m1*(y2-y1), z1+m1*(z2-z1))
- Return p
- Else
- Local p:TAlgoPoint3D[]=New TAlgoPoint3D[2]
- p[0]=TAlgoPoint3D.Create( x1+m1*(x2-x1), y1+m1*(y2-y1), z1+m1*(z2-z1))
- p[1]=TAlgoPoint3D.Create( x1+m2*(x2-x1), y1+m2*(y2-y1), z1+m2*(z2-z1))
- Return p
- EndIf
- EndIf
-
-End Function
-
-
-Private
-
-Type AlgoStatic
- Global done:Int=False
- Global si:Double[]
- Global co:Double[]
-
- Function Init()
- If Not done
- si=New Double[3600]
- co=New Double[3600]
-
- For Local f:Int=0 To 3599
- si[f]=Sin(Double(f)/10)
- co[f]=Cos(Double(f)/10)
- Next
-
- done=True
- EndIf
- End Function
-End Type
-
-Function Square:Double(x:Double)
- Return x*x
-End Function
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.algorithm
+EndRem
+Module noddybox.algorithm
+
+ModuleInfo "Framework: Various algorithm routines"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.math
+Import brl.linkedlist
+
+Rem
+bbdoc: Used to return integer points from algorithms.
+EndRem
+Type TAlgoPoint
+ Rem
+ bbdoc: The X co-ordinate of the point
+ EndRem
+ Field x:Int
+ Rem
+ bbdoc: The Y co-ordinate of the point
+ EndRem
+ Field y:Int
+
+ Rem
+ bbdoc: Create a point.
+ returns: Newly created point.
+ about: @x and @y are initialised with the passed parameters.
+ EndRem
+ Function Create:TAlgoPoint(x:Int, y:Int)
+ Local o:TAlgoPoint=New TAlgoPoint
+ o.x=x
+ o.y=y
+ Return o
+ End Function
+
+End Type
+
+Rem
+bbdoc: Used to return double points from algorithms.
+EndRem
+Type TAlgoPointD
+ Rem
+ bbdoc: The X co-ordinate of the point
+ EndRem
+ Field x:Double
+ Rem
+ bbdoc: The Y co-ordinate of the point
+ EndRem
+ Field y:Double
+
+ Rem
+ bbdoc: Create a point.
+ returns: Newly created point.
+ about: @x and @y are initialised with the passed parameters.
+ EndRem
+ Function Create:TAlgoPointD(x:Double, y:Double)
+ Local o:TAlgoPointD=New TAlgoPointD
+ o.x=x
+ o.y=y
+ Return o
+ End Function
+
+End Type
+
+Rem
+bbdoc: Used to return 3D points from algorithms.
+EndRem
+Type TAlgoPoint3D
+ Rem
+ bbdoc: The X co-ordinate of the point
+ EndRem
+ Field x:Double
+ Rem
+ bbdoc: The Y co-ordinate of the point
+ EndRem
+ Field y:Double
+ Rem
+ bbdoc: The Z co-ordinate of the point
+ EndRem
+ Field z:Double
+
+ Rem
+ bbdoc: Create a point.
+ returns: Newly created point.
+ about: @x, @y and @z are initialised with the passed parameters.
+ EndRem
+ Function Create:TAlgoPoint3D(x:Double, y:Double, z:Double)
+ Local o:TAlgoPoint3D=New TAlgoPoint3D
+ o.x=x
+ o.y=y
+ o.z=z
+ Return o
+ End Function
+
+End Type
+
+Rem
+bbdoc: Rotates a point.
+returns: The rotated point.
+about: @x, @y are rotated around 0,0 by @angle, which is the value in degrees multiplied by ten.
+about: To speed things up a simple 3600 element lookup table is used, so @angle <u>must</u> be 0 to 3599 inclusive, or a runtime error will result.
+EndRem
+Function DoRotate:TAlgoPoint(x:Int, y:Int, angle:Int)
+ AlgoStatic.Init()
+
+ Local dx:Double=x
+ Local dy:Double=y
+ Local dco:Double=AlgoStatic.co[angle]
+ Local dsi:Double=algoStatic.si[angle]
+
+ Return TAlgoPoint.Create(dco*dx+(-dsi)*dy,dsi*dx+dco*dy)
+End Function
+
+Rem
+bbdoc: Rotates a point (double version)
+returns: The rotated point.
+about: @x, @y are rotated around 0,0 by @angle, which is the value in degrees multiplied by ten.
+about: To speed things up a simple 3600 element lookup table is used, so @angle <u>must</u> be 0 to 3599 inclusive, or a runtime error will result.
+EndRem
+Function DoRotateD:TAlgoPointD(x:Double, y:Double, angle:Int)
+ AlgoStatic.Init()
+
+ Local dco:Double=AlgoStatic.co[angle]
+ Local dsi:Double=algoStatic.si[angle]
+
+ Return TAlgoPointD.Create(dco*x+(-dsi)*y,dsi*x+dco*y)
+End Function
+
+Rem
+bbdoc: Implements a Bresenham style line.
+returns: A list of points making up the line.
+about: @px1, @py1, @px2 and @py2 are the end points of the line.
+EndRem
+Function DoLine:TList(p1x:Int, p1y:Int, p2x:Int, p2y:Int)
+ Local list:TList=CreateList()
+ Local f:Int
+ Local dx:Int
+ Local dy:Int
+ Local ix:Int
+ Local iy:Int
+ Local incrE:Int
+ Local incrNE:Int
+ Local d:Int
+ Local x:Int
+ Local y:Int
+ Local ymode:Int
+
+ dx=p2x-p1x
+ dy=p2y-p1y
+
+ ix=Sgn(dx)
+ iy=Sgn(dy)
+
+ dx=Abs(dx)
+ dy=Abs(dy)
+
+ If dy>dx
+ ymode=True
+ d=dx*2-dy
+ incrE=dx*2
+ incrNE=(dx-dy)*2
+ Else
+ ymode=False
+ d=dy*2-dx
+ incrE=dy*2
+ incrNE=(dy-dx)*2
+ EndIf
+
+ x=p1x
+ y=p1y
+
+ list.AddLast(TAlgoPoint.Create(x,y))
+
+ If ymode
+ While y<>p2y
+ If d<=0
+ d:+incrE
+ y:+iy
+ Else
+ d:+incrNE
+ y:+iy
+ x:+ix
+ EndIf
+
+ list.AddLast(TAlgoPoint.Create(x,y))
+ Wend
+ Else
+ While x<>p2x
+ If d<=0
+ d:+incrE
+ x:+ix
+ Else
+ d:+incrNE
+ y:+iy
+ x:+ix
+ EndIf
+
+ list.AddLast(TAlgoPoint.Create(x,y))
+ Wend
+ EndIf
+
+ Return list
+End Function
+
+
+Rem
+bbdoc: Returns the points for degrees 0-359 on the described circle.
+returns: A list of points making up the circle.
+about: @x, @y is the centre of the circle, @r it's radius.
+EndRem
+Function DoCircle:TAlgoPoint[](x:Int, y:Int, r:Int)
+ Local p:TAlgoPoint[]=New TAlgoPoint[360]
+ Local f:Int
+
+ AlgoStatic.Init()
+
+ For f=0 To 359
+ p[f]=TAlgoPoint.Create(x+r*AlgoStatic.si[f*10],y+r*AlgoStatic.co[f*10])
+ Next
+
+ Return p
+End Function
+
+
+Rem
+bbdoc: Returns the points where a sphere intersects a 3D line.
+returns: null if they don't intersect, one point if it intersects as a tangent, two points otherwise.
+about: @x1, @y1, @z1, @x2, @y2 and @z2 describe the line. @cx, @cy, @cz and @rad describe the sphere.
+about: Leave the Z co-ords as zero to do a 2D check.
+EndRem
+Function CircleIntersects:TAlgoPoint3D[](x1:Double, y1:Double, z1:Double, x2:Double, y2:Double, z2:Double, cx:Double, cy:Double, cz:Double, rad:Double)
+ Local a:Double = Square(x2-x1) + Square(y2-y1) + Square(z2-z1)
+ Local b:Double = 2 * ( (x2-x1)*(x1-cx) + (y2-y1)*(y1-cy) + (z2-z1)*(z1-cz) )
+ Local c:Double = Square(x1) + Square(y1) + Square(z1) + Square(cx) + Square(cy) + Square(cz) - 2 * ( cx*x1 + cy*y1 + cz*z1 ) - Square(rad)
+ Local i:Double = b*b-4*a*c
+
+ If i<0
+ Return Null
+ ElseIf i=1.0
+ Local m:Double = -b/(2*a)
+ If m<0.0 Or m>1.0
+ Return Null
+ EndIf
+ Local p:TAlgoPoint3D[]=New TAlgoPoint3D[1]
+ p[0]=TAlgoPoint3D.Create( x1+m*(x2-x1), y1+m*(y2-y1), z1 + m*(z2-z1))
+ Return p
+ Else
+ Local e:Double = Sqr(Square(b) - 4*a*c)
+ Local m1:Double = (-b + e) / (2*a)
+ Local m2:Double = (-b - e) / (2*a)
+
+ If (m2<0.0 Or m2>1.0) And (m1<0.0 Or m1>1.0)
+ Return Null
+ ElseIf (m1<0.0 Or m1>1.0)
+ Local p:TAlgoPoint3D[]=New TAlgoPoint3D[1]
+ p[0]=TAlgoPoint3D.Create( x1+m2*(x2-x1), y1+m2*(y2-y1), z1+m2*(z2-z1))
+ Return p
+ ElseIf m2<0.0 Or m2>1.0
+ Local p:TAlgoPoint3D[]=New TAlgoPoint3D[1]
+ p[0]=TAlgoPoint3D.Create( x1+m1*(x2-x1), y1+m1*(y2-y1), z1+m1*(z2-z1))
+ Return p
+ Else
+ Local p:TAlgoPoint3D[]=New TAlgoPoint3D[2]
+ p[0]=TAlgoPoint3D.Create( x1+m1*(x2-x1), y1+m1*(y2-y1), z1+m1*(z2-z1))
+ p[1]=TAlgoPoint3D.Create( x1+m2*(x2-x1), y1+m2*(y2-y1), z1+m2*(z2-z1))
+ Return p
+ EndIf
+ EndIf
+
+End Function
+
+
+Private
+
+Type AlgoStatic
+ Global done:Int=False
+ Global si:Double[]
+ Global co:Double[]
+
+ Function Init()
+ If Not done
+ si=New Double[3600]
+ co=New Double[3600]
+
+ For Local f:Int=0 To 3599
+ si[f]=Sin(Double(f)/10)
+ co[f]=Cos(Double(f)/10)
+ Next
+
+ done=True
+ EndIf
+ End Function
+End Type
+
+Function Square:Double(x:Double)
+ Return x*x
+End Function
diff --git a/bitmapfont.mod/bitmapfont.bmx b/bitmapfont.mod/bitmapfont.bmx
index de7edb2..896346f 100644
--- a/bitmapfont.mod/bitmapfont.bmx
+++ b/bitmapfont.mod/bitmapfont.bmx
@@ -1,221 +1,217 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.bitmapfont
-EndRem
-Module noddybox.bitmapfont
-
-ModuleInfo "Framework: Simple Bitmap Font Routines"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-
-Import brl.Max2D
-Import brl.Basic
-
-
-Strict
-
-Rem
-bbdoc: Defines a bitmap font
-about: The @TBitmapFont object works from BMF Files, which are created using a tool called BitmapFontEd available at
-<a href="http://www.noddybox.demon.co.uk/free/index-csharp.html">http://www.noddybox.demon.co.uk/free/index-csharp.html</a><br>
-Note that when colours are referenced they simply modify the colours in the font images as @SetColor() would do on a norml image.<br>
-When drawing characters the current scale, alpha and rotation settings are applied.
-EndRem
-Type TBitmapFont
-
- Const NOCHR=95
-
- Field img:TImage[NOCHR]
- Field height:Int[NOCHR]
- Field width:Int[NOCHR]
- Field is_fixed:Int
- Field max_width:Int
- Field max_height:Int
-
- Rem
- bbdoc: Loads a font from the supplied BMF file.
- returns: The created font, or null if the BMF file couldn't be loaded.
- about: The @image_flags are passed onto @CreateImage() when the images for the font are being created.
- EndRem
- Function Load:TBitmapFont(path:String, image_flags:Int)
- Local fnt:TBitmapFont
- Local str:TStream
- Local magic:String
- Local f,x,y
-
- str=ReadStream(path)
-
- If (Not str) Then Return Null
-
- fnt=New TBitmapFont
-
- magic=ReadString(str,4)
-
- If (magic<>"BMF1")
- CloseStream(str)
- Return Null
- EndIf
-
- fnt.max_width=-1
- fnt.max_height=-1
-
- fnt.is_fixed=ReadInt(str)
-
- For f=0 Until NOCHR
- fnt.width[f]=ReadInt(str)
- fnt.height[f]=ReadInt(str)
-
- fnt.max_width=Max(fnt.max_width,fnt.width[f])
- fnt.max_height=Max(fnt.max_height,fnt.height[f])
-
- fnt.img[f]=CreateImage(fnt.width[f],fnt.height[f],1,image_flags)
-
- Local pm:TPixmap=LockImage(fnt.img[f])
-
- For x=0 Until fnt.width[f]
- For y=0 Until fnt.height[f]
- WritePixel(pm,x,y,ReadInt(str))
- Next
- Next
-
- UnlockImage(fnt.img[f])
- Next
-
- CloseStream(str)
-
- Return fnt
- End Function
-
- Rem
- bbdoc: Draws text.
- about: Draws @txt at the supplied @x, @y co-ordinates. @red, @green and @blue control the colour.
- EndRem
- Method Draw(txt:String, x:Int, y:Int, red:Int=255, green:Int=255, blue:Int=255)
- Local f,r,g,b,c
- Local xs#,ys#
-
- GetScale(xs,ys)
-
- GetColor(r,g,b)
- SetColor(red,green,blue)
-
- For f=0 Until Len(txt)
- c=txt[f]-32
- DrawImage(img[c],x,y)
- x:+width[c]*xs
- Next
-
- SetColor(r,g,b)
- End Method
-
- Rem
- bbdoc: Draws centred text.
- about: Draws @txt centred at the supplied @y co-ordinate. @red, @green and @blue control the colour.
- EndRem
- Method Centre(txt:String, y:Int, red:Int=255, green:Int=255, blue:Int=255)
- If is_fixed
- Draw(txt,GraphicsWidth()/2-Len(txt)*width[0]/2,y,red,green,blue)
- Else
- Draw(txt,GraphicsWidth()/2-TextWidth(txt)/2,y,red,green,blue)
- EndIf
- End Method
-
- Rem
- bbdoc: Draws text centred on a position.
- about: Draws @txt centred on the supplied @x and @y co-ordinate. @red, @green and @blue control the colour.
- EndRem
- Method CentreOn(txt:String, x:Int, y:Int, red:Int=255, green:Int=255, blue:Int=255)
- If is_fixed
- Draw(txt,x-Len(txt)*width[0]/2,y-TextHeight(txt),red,green,blue)
- Else
- Draw(txt,x-TextWidth(txt)/2,y-TextHeight(txt),red,green,blue)
- EndIf
- End Method
-
- Rem
- bbdoc: Draws text right justified.
- about: Draws @txt right justified on the supplied @x and @y co-ordinate. @red, @green and @blue control the colour.
- EndRem
- Method DrawRight(txt:String, x:Int, y:Int, red:Int=255, green:Int=255, blue:Int=255)
- If is_fixed
- Draw(txt,x-Len(txt)*width[0],y,red,green,blue)
- Else
- Draw(txt,x-TextWidth(txt),y,red,green,blue)
- EndIf
- End Method
-
- Rem
- bbdoc: Width of the supplied string.
- returns: The length of the string @txt in pixels.
- about: The current scale settings are taken into account.
- EndRem
- Method TextWidth:Int(txt:String)
- Local w
- Local xs#,ys#
-
- GetScale(xs,ys)
-
- For Local f=0 Until Len(txt)
- w:+width[txt[f]-32]*xs
- Next
- Return w
- End Method
-
- Rem
- bbdoc: Height of the supplied string.
- returns: The height of the string @txt in pixels.
- about: The current scale settings are taken into account.
- EndRem
- Method TextHeight:Int(txt:String)
- Local h:Int=0
- Local xs#,ys#
-
- GetScale(xs,ys)
-
- For Local f=0 Until Len(txt)
- h=Max(h,height[txt[f]-32]*ys)
- Next
-
- Return h
- End Method
-
- Rem
- bbdoc: Width of the largest character.
- returns: The width in pixels of the largest character in the font.
- EndRem
- Method MaxWidth:Int()
- Return max_width
- End Method
-
- Rem
- bbdoc: Height of the largest character.
- returns: The height in pixels of the largest character in the font.
- EndRem
- Method MaxHeight:Int()
- Return max_height
- End Method
-
-End Type
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.bitmapfont
+EndRem
+Module noddybox.bitmapfont
+
+ModuleInfo "Framework: Simple Bitmap Font Routines"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.Max2D
+Import brl.Basic
+
+Rem
+bbdoc: Defines a bitmap font
+about: The @TBitmapFont object works from BMF Files, which are created using a tool called BitmapFontEd available at
+<a href="http://www.noddybox.demon.co.uk/free/index-csharp.html">http://www.noddybox.demon.co.uk/free/index-csharp.html</a><br>
+Note that when colours are referenced they simply modify the colours in the font images as @SetColor() would do on a norml image.<br>
+When drawing characters the current scale, alpha and rotation settings are applied.
+EndRem
+Type TBitmapFont
+
+ Const NOCHR=95
+
+ Field img:TImage[NOCHR]
+ Field height:Int[NOCHR]
+ Field width:Int[NOCHR]
+ Field is_fixed:Int
+ Field max_width:Int
+ Field max_height:Int
+
+ Rem
+ bbdoc: Loads a font from the supplied BMF file.
+ returns: The created font, or null if the BMF file couldn't be loaded.
+ about: The @image_flags are passed onto @CreateImage() when the images for the font are being created.
+ EndRem
+ Function Load:TBitmapFont(path:String, image_flags:Int)
+ Local fnt:TBitmapFont
+ Local str:TStream
+ Local magic:String
+ Local f,x,y
+
+ str=ReadStream(path)
+
+ If (Not str) Then Return Null
+
+ fnt=New TBitmapFont
+
+ magic=ReadString(str,4)
+
+ If (magic<>"BMF1")
+ CloseStream(str)
+ Return Null
+ EndIf
+
+ fnt.max_width=-1
+ fnt.max_height=-1
+
+ fnt.is_fixed=ReadInt(str)
+
+ For f=0 Until NOCHR
+ fnt.width[f]=ReadInt(str)
+ fnt.height[f]=ReadInt(str)
+
+ fnt.max_width=Max(fnt.max_width,fnt.width[f])
+ fnt.max_height=Max(fnt.max_height,fnt.height[f])
+
+ fnt.img[f]=CreateImage(fnt.width[f],fnt.height[f],1,image_flags)
+
+ Local pm:TPixmap=LockImage(fnt.img[f])
+
+ For x=0 Until fnt.width[f]
+ For y=0 Until fnt.height[f]
+ WritePixel(pm,x,y,ReadInt(str))
+ Next
+ Next
+
+ UnlockImage(fnt.img[f])
+ Next
+
+ CloseStream(str)
+
+ Return fnt
+ End Function
+
+ Rem
+ bbdoc: Draws text.
+ about: Draws @txt at the supplied @x, @y co-ordinates. @red, @green and @blue control the colour.
+ EndRem
+ Method Draw(txt:String, x:Int, y:Int, red:Int=255, green:Int=255, blue:Int=255)
+ Local f,r,g,b,c
+ Local xs#,ys#
+
+ GetScale(xs,ys)
+
+ GetColor(r,g,b)
+ SetColor(red,green,blue)
+
+ For f=0 Until Len(txt)
+ c=txt[f]-32
+ DrawImage(img[c],x,y)
+ x:+width[c]*xs
+ Next
+
+ SetColor(r,g,b)
+ End Method
+
+ Rem
+ bbdoc: Draws centred text.
+ about: Draws @txt centred at the supplied @y co-ordinate. @red, @green and @blue control the colour.
+ EndRem
+ Method Centre(txt:String, y:Int, red:Int=255, green:Int=255, blue:Int=255)
+ If is_fixed
+ Draw(txt,GraphicsWidth()/2-Len(txt)*width[0]/2,y,red,green,blue)
+ Else
+ Draw(txt,GraphicsWidth()/2-TextWidth(txt)/2,y,red,green,blue)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Draws text centred on a position.
+ about: Draws @txt centred on the supplied @x and @y co-ordinate. @red, @green and @blue control the colour.
+ EndRem
+ Method CentreOn(txt:String, x:Int, y:Int, red:Int=255, green:Int=255, blue:Int=255)
+ If is_fixed
+ Draw(txt,x-Len(txt)*width[0]/2,y-TextHeight(txt),red,green,blue)
+ Else
+ Draw(txt,x-TextWidth(txt)/2,y-TextHeight(txt),red,green,blue)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Draws text right justified.
+ about: Draws @txt right justified on the supplied @x and @y co-ordinate. @red, @green and @blue control the colour.
+ EndRem
+ Method DrawRight(txt:String, x:Int, y:Int, red:Int=255, green:Int=255, blue:Int=255)
+ If is_fixed
+ Draw(txt,x-Len(txt)*width[0],y,red,green,blue)
+ Else
+ Draw(txt,x-TextWidth(txt),y,red,green,blue)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Width of the supplied string.
+ returns: The length of the string @txt in pixels.
+ about: The current scale settings are taken into account.
+ EndRem
+ Method TextWidth:Int(txt:String)
+ Local w
+ Local xs#,ys#
+
+ GetScale(xs,ys)
+
+ For Local f=0 Until Len(txt)
+ w:+width[txt[f]-32]*xs
+ Next
+ Return w
+ End Method
+
+ Rem
+ bbdoc: Height of the supplied string.
+ returns: The height of the string @txt in pixels.
+ about: The current scale settings are taken into account.
+ EndRem
+ Method TextHeight:Int(txt:String)
+ Local h:Int=0
+ Local xs#,ys#
+
+ GetScale(xs,ys)
+
+ For Local f=0 Until Len(txt)
+ h=Max(h,height[txt[f]-32]*ys)
+ Next
+
+ Return h
+ End Method
+
+ Rem
+ bbdoc: Width of the largest character.
+ returns: The width in pixels of the largest character in the font.
+ EndRem
+ Method MaxWidth:Int()
+ Return max_width
+ End Method
+
+ Rem
+ bbdoc: Height of the largest character.
+ returns: The height in pixels of the largest character in the font.
+ EndRem
+ Method MaxHeight:Int()
+ Return max_height
+ End Method
+
+End Type
diff --git a/gfxmenu.mod/gfxmenu.bmx b/gfxmenu.mod/gfxmenu.bmx
index 92ce08c..26364d5 100644
--- a/gfxmenu.mod/gfxmenu.bmx
+++ b/gfxmenu.mod/gfxmenu.bmx
@@ -1,207 +1,205 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.gfxmenu
-EndRem
-Module noddybox.gfxmenu
-
-ModuleInfo "Framework: Simple Graphical Menu"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-
-Strict
-Import brl.linkedlist
-Import brl.max2d
-
-Rem
-bbdoc: Allows a menu backdrop to be automatically processed. Derive a class from this to use.
-EndRem
-Type TGfxMenuBackdrop Abstract
- Rem
- bbdoc: Create a menu backdrop element.
- returns: The created elemnt.
- about: Notice that this is a method, rather than the usual function creator.
- EndRem
- Method Create:TGfxMenuBackdrop() Abstract
- Rem
- bbdoc: Called by the menu to update the backdrop.
- EndRem
- Method Update() Abstract
-End Type
-
-Rem
-bbdoc: Defines a graphical menu.
-EndRem
-Type TGfxMenu
- Field list:TList
- Field bdrop:TList
- Field mbdown:Int
- Field r:Int
- Field g:Int
- Field b:Int
- Field over_r:Int
- Field over_g:Int
- Field over_b:Int
- Field fade:Int
-
- Rem
- bbdoc: Create a menu.
- returns: The created menu.
- about: @backdrop is the backdrop to create (null for no backdrop). @num is the number of backdrop items to create.
- SetColor() is called with @r, @g and @b when the mouse is not over an item, overwise SetColor() is
- called with @over_r, @over_g and @over_b when the item is active. @fade is the amount colours will alter as the
- mouse hovers over buttons. Set this to 255 to make colour changes instant.
- EndRem
- Function Create:TGfxMenu(r:Int=164, g:Int=164, b:Int=164, over_r:Int=255, over_g:Int=255, over_b:Int=255, fade:Int=5, backdrop:TGfxMenuBackdrop=Null, num:Int=0)
- Local menu:TGfxMenu=New TGfxMenu
-
- menu.list=New TList
- menu.bdrop=New TList
- menu.mbdown=False
-
- menu.r=r
- menu.g=g
- menu.b=b
- menu.over_r=over_r
- menu.over_g=over_g
- menu.over_b=over_b
- menu.fade=fade
-
- If backdrop
- For Local f:Int=0 Until num
- menu.bdrop.AddLast(backdrop.Create())
- Next
- EndIf
-
- Return menu
- End Function
-
- Rem
- bbdoc: Adds a menu item.
- returns: The created menu.
- about: @x and @y are the position to draw the image at. If @x is -1 then the image is centred. @i is the image.
- @id is the value returned from @Render() for this menu item. Don't use -1 for this!
- EndRem
- Method Add(x:Int, y:Int, i:TImage, id:Int)
- list.AddLast(TGfxMenuOpt.Create(x,y,i,id,r,g,b))
- End Method
-
- Rem
- bbdoc: Renders and updates the menu.
- returns: The selected item, or -1 if nothing clicked.
- about: Set @hide to True to hide the menu (the backdrop is still updated). SetColor() may have changed when this routine exits.
- EndRem
- Method Render:Int(hide:Int)
- For Local p:TGfxMenuBackdrop=EachIn bdrop
- p.Update()
- Next
-
- If hide
- Return -1
- EndIf
-
- Local in:Int=-1
- Local mx:Int=MouseX()
- Local my:Int=MouseY()
- Local any:Int=False
-
- For Local opt:TGfxMenuOpt=EachIn list
- If opt.InBox(mx,my)
- opt.r=Towards(over_r,opt.r)
- opt.g=Towards(over_g,opt.g)
- opt.b=Towards(over_b,opt.b)
- SetColor(opt.r,opt.g,opt.b)
-
- If MouseDown(1)
- mbdown=True
- DrawImage(opt.i,opt.x,opt.y+2)
- any=True
- Else
- DrawImage(opt.i,opt.x,opt.y)
- If mbdown
- in=opt.id
- EndIf
- mbdown=False
- EndIf
- Else
- opt.r=Towards(r,opt.r)
- opt.g=Towards(g,opt.g)
- opt.b=Towards(b,opt.b)
- SetColor(opt.r,opt.g,opt.b)
- DrawImage(opt.i,opt.x,opt.y)
- EndIf
- Next
-
- If Not any
- mbdown=False
- EndIf
-
- Return in
- End Method
-
- Method Towards:Int(dest:Int, val:Int)
- If val<dest
- Return Min(dest,val+fade)
- ElseIf val>dest
- Return Max(dest,val-fade)
- EndIf
-
- Return val
- End Method
-End Type
-
-Private
-
-Type TGfxMenuOpt
- Field x:Int
- Field y:Int
- Field i:TImage
- Field id:Int
- Field r:Int
- Field g:Int
- Field b:Int
-
- Function Create:TGfxMenuOpt(x:Int, y:Int, i:TImage, id:Int, r:Int, g:Int, b:Int)
- Local o:TGfxMenuOpt=New TGfxMenuOpt
-
- If x=-1
- x=(GraphicsWidth()-ImageWidth(i))/2
- EndIf
-
- o.x=x
- o.y=y
- o.i=i
- o.id=id
- o.r=r
- o.g=g
- o.b=b
-
- Return o
- End Function
-
- Method InBox:Int(mx:Int, my:Int)
- Return mx>=x And my>=y And mx<=x+ImageWidth(i) And my<=y+ImageHeight(i)
- End Method
-End Type
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.gfxmenu
+EndRem
+Module noddybox.gfxmenu
+
+ModuleInfo "Framework: Simple Graphical Menu"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.linkedlist
+Import brl.max2d
+
+Rem
+bbdoc: Allows a menu backdrop to be automatically processed. Derive a class from this to use.
+EndRem
+Type TGfxMenuBackdrop Abstract
+ Rem
+ bbdoc: Create a menu backdrop element.
+ returns: The created elemnt.
+ about: Notice that this is a method, rather than the usual function creator.
+ EndRem
+ Method Create:TGfxMenuBackdrop() Abstract
+ Rem
+ bbdoc: Called by the menu to update the backdrop.
+ EndRem
+ Method Update() Abstract
+End Type
+
+Rem
+bbdoc: Defines a graphical menu.
+EndRem
+Type TGfxMenu
+ Field list:TList
+ Field bdrop:TList
+ Field mbdown:Int
+ Field r:Int
+ Field g:Int
+ Field b:Int
+ Field over_r:Int
+ Field over_g:Int
+ Field over_b:Int
+ Field fade:Int
+
+ Rem
+ bbdoc: Create a menu.
+ returns: The created menu.
+ about: @backdrop is the backdrop to create (null for no backdrop). @num is the number of backdrop items to create.
+ SetColor() is called with @r, @g and @b when the mouse is not over an item, overwise SetColor() is
+ called with @over_r, @over_g and @over_b when the item is active. @fade is the amount colours will alter as the
+ mouse hovers over buttons. Set this to 255 to make colour changes instant.
+ EndRem
+ Function Create:TGfxMenu(r:Int=164, g:Int=164, b:Int=164, over_r:Int=255, over_g:Int=255, over_b:Int=255, fade:Int=5, backdrop:TGfxMenuBackdrop=Null, num:Int=0)
+ Local menu:TGfxMenu=New TGfxMenu
+
+ menu.list=New TList
+ menu.bdrop=New TList
+ menu.mbdown=False
+
+ menu.r=r
+ menu.g=g
+ menu.b=b
+ menu.over_r=over_r
+ menu.over_g=over_g
+ menu.over_b=over_b
+ menu.fade=fade
+
+ If backdrop
+ For Local f:Int=0 Until num
+ menu.bdrop.AddLast(backdrop.Create())
+ Next
+ EndIf
+
+ Return menu
+ End Function
+
+ Rem
+ bbdoc: Adds a menu item.
+ returns: The created menu.
+ about: @x and @y are the position to draw the image at. If @x is -1 then the image is centred. @i is the image.
+ @id is the value returned from @Render() for this menu item. Don't use -1 for this!
+ EndRem
+ Method Add(x:Int, y:Int, i:TImage, id:Int)
+ list.AddLast(TGfxMenuOpt.Create(x,y,i,id,r,g,b))
+ End Method
+
+ Rem
+ bbdoc: Renders and updates the menu.
+ returns: The selected item, or -1 if nothing clicked.
+ about: Set @hide to True to hide the menu (the backdrop is still updated). SetColor() may have changed when this routine exits.
+ EndRem
+ Method Render:Int(hide:Int)
+ For Local p:TGfxMenuBackdrop=EachIn bdrop
+ p.Update()
+ Next
+
+ If hide
+ Return -1
+ EndIf
+
+ Local in:Int=-1
+ Local mx:Int=MouseX()
+ Local my:Int=MouseY()
+ Local any:Int=False
+
+ For Local opt:TGfxMenuOpt=EachIn list
+ If opt.InBox(mx,my)
+ opt.r=Towards(over_r,opt.r)
+ opt.g=Towards(over_g,opt.g)
+ opt.b=Towards(over_b,opt.b)
+ SetColor(opt.r,opt.g,opt.b)
+
+ If MouseDown(1)
+ mbdown=True
+ DrawImage(opt.i,opt.x,opt.y+2)
+ any=True
+ Else
+ DrawImage(opt.i,opt.x,opt.y)
+ If mbdown
+ in=opt.id
+ EndIf
+ mbdown=False
+ EndIf
+ Else
+ opt.r=Towards(r,opt.r)
+ opt.g=Towards(g,opt.g)
+ opt.b=Towards(b,opt.b)
+ SetColor(opt.r,opt.g,opt.b)
+ DrawImage(opt.i,opt.x,opt.y)
+ EndIf
+ Next
+
+ If Not any
+ mbdown=False
+ EndIf
+
+ Return in
+ End Method
+
+ Method Towards:Int(dest:Int, val:Int)
+ If val<dest
+ Return Min(dest,val+fade)
+ ElseIf val>dest
+ Return Max(dest,val-fade)
+ EndIf
+
+ Return val
+ End Method
+End Type
+
+Private
+
+Type TGfxMenuOpt
+ Field x:Int
+ Field y:Int
+ Field i:TImage
+ Field id:Int
+ Field r:Int
+ Field g:Int
+ Field b:Int
+
+ Function Create:TGfxMenuOpt(x:Int, y:Int, i:TImage, id:Int, r:Int, g:Int, b:Int)
+ Local o:TGfxMenuOpt=New TGfxMenuOpt
+
+ If x=-1
+ x=(GraphicsWidth()-ImageWidth(i))/2
+ EndIf
+
+ o.x=x
+ o.y=y
+ o.i=i
+ o.id=id
+ o.r=r
+ o.g=g
+ o.b=b
+
+ Return o
+ End Function
+
+ Method InBox:Int(mx:Int, my:Int)
+ Return mx>=x And my>=y And mx<=x+ImageWidth(i) And my<=y+ImageHeight(i)
+ End Method
+End Type
diff --git a/keysyms.mod/keysyms.bmx b/keysyms.mod/keysyms.bmx
index 9dd7f38..425eee1 100644
--- a/keysyms.mod/keysyms.bmx
+++ b/keysyms.mod/keysyms.bmx
@@ -1,184 +1,182 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.keysyms
-EndRem
-Module noddybox.keysyms
-
-ModuleInfo "Framework: English string symbols for keycodes"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-
-Import brl.keycodes
-
-Rem
-bbdoc: Get a keysym.
-returns: The string name of @keycode, or "Unknown" for unknown codes.
-EndRem
-Function KeySym:String(keycode:Int)
- KeySymStatic.Init()
-
- If keycode<0 Or keycode>=KeySymStatic.codes.length
- Return "Unknown"
- EndIf
-
- If KeySymStatic.codes[keycode]
- Return KeySymStatic.codes[keycode]
- Else
- Return "Unknown"
- EndIf
-End Function
-
-Private
-
-Type KeySymStatic
- Global done:Int=False
- Global codes:String[]
-
- Function Init()
- If Not done
-
- ' TODO: This will break if keycodes are ever above 511
- '
- codes=New String[512]
-
- codes[MOUSE_LEFT] = "Left Mouse button"
- codes[MOUSE_RIGHT] = "Right Mouse button"
- codes[MOUSE_MIDDLE] = "Middle Mouse button"
- codes[KEY_BACKSPACE] = "Backspace"
- codes[KEY_TAB] = "Tab"
- codes[KEY_RETURN] = "Return"
- codes[KEY_CLEAR] = "Clear"
- codes[KEY_ENTER] = "Enter"
- 'codes[KEY_PAUSE] = "Pause"
- 'codes[KEY_CAPSLOCK] = "Caps Lock"
- codes[KEY_ESCAPE] = "Escape"
- codes[KEY_SPACE] = "Space"
- codes[KEY_PAGEUP] = "Page Up"
- codes[KEY_PAGEDOWN] = "Page Down"
- codes[KEY_END] = "End"
- codes[KEY_HOME] = "Home"
- codes[KEY_LEFT] = "Left"
- codes[KEY_UP] = "Up"
- codes[KEY_RIGHT] = "Right"
- codes[KEY_DOWN] = "Down"
- codes[KEY_SELECT] = "Select"
- codes[KEY_PRINT] = "Print"
- codes[KEY_EXECUTE] = "Execute"
- codes[KEY_SCREEN] = "Screen"
- codes[KEY_INSERT] = "Insert"
- codes[KEY_DELETE] = "Delete"
- 'codes[KEY_HELP] = "Help"
- codes[KEY_0] = "0"
- codes[KEY_1] = "1"
- codes[KEY_2] = "2"
- codes[KEY_3] = "3"
- codes[KEY_4] = "4"
- codes[KEY_5] = "5"
- codes[KEY_6] = "6"
- codes[KEY_7] = "7"
- codes[KEY_8] = "8"
- codes[KEY_9] = "9"
- codes[KEY_A] = "A"
- codes[KEY_B] = "B"
- codes[KEY_C] = "C"
- codes[KEY_D] = "D"
- codes[KEY_E] = "E"
- codes[KEY_F] = "F"
- codes[KEY_G] = "G"
- codes[KEY_H] = "H"
- codes[KEY_I] = "I"
- codes[KEY_J] = "J"
- codes[KEY_K] = "K"
- codes[KEY_L] = "L"
- codes[KEY_M] = "M"
- codes[KEY_N] = "N"
- codes[KEY_O] = "O"
- codes[KEY_P] = "P"
- codes[KEY_Q] = "Q"
- codes[KEY_R] = "R"
- codes[KEY_S] = "S"
- codes[KEY_T] = "T"
- codes[KEY_U] = "U"
- codes[KEY_V] = "V"
- codes[KEY_W] = "W"
- codes[KEY_X] = "X"
- codes[KEY_Y] = "Y"
- codes[KEY_Z] = "Z"
- codes[KEY_LSYS] = "Left Sys"
- codes[KEY_RSYS] = "Right Sys"
- codes[KEY_NUM0] = "Numpad 0"
- codes[KEY_NUM1] = "Numpad 1"
- codes[KEY_NUM2] = "Numpad 2"
- codes[KEY_NUM3] = "Numpad 3"
- codes[KEY_NUM4] = "Numpad 4"
- codes[KEY_NUM5] = "Numpad 5"
- codes[KEY_NUM6] = "Numpad 6"
- codes[KEY_NUM7] = "Numpad 7"
- codes[KEY_NUM8] = "Numpad 8"
- codes[KEY_NUM9] = "Numpad 9"
- codes[KEY_NUMMULTIPLY] = "Numpad *"
- codes[KEY_NUMADD] = "Numpad +"
- codes[KEY_NUMDIVIDE] = "Numpad /"
- codes[KEY_NUMSUBTRACT] = "Numpad -"
- codes[KEY_NUMDECIMAL] = "Numpad ."
- codes[KEY_NUMDIVIDE] = "Numpad /"
- codes[KEY_F1] = "F1"
- codes[KEY_F2] = "F2"
- codes[KEY_F3] = "F3"
- codes[KEY_F4] = "F4"
- codes[KEY_F5] = "F5"
- codes[KEY_F6] = "F6"
- codes[KEY_F7] = "F7"
- codes[KEY_F8] = "F8"
- codes[KEY_F9] = "F9"
- codes[KEY_F10] = "F10"
- codes[KEY_F11] = "F11"
- codes[KEY_F12] = "F12"
- 'codes[KEY_NUMLOCK] = "Num Lock"
- 'codes[KEY_SCROLL] = "Scroll Lock"
- codes[KEY_LSHIFT] = "Left Shift"
- codes[KEY_RSHIFT] = "Right Shift"
- codes[KEY_LCONTROL] = "Left Control"
- codes[KEY_RCONTROL] = "Right Control"
- codes[KEY_LALT] = "Left Alt"
- codes[KEY_RALT] = "Right Alt"
- codes[KEY_TILDE] = "Tilde"
- codes[KEY_MINUS] = "Minus"
- codes[KEY_EQUALS] = "Equals"
- codes[KEY_OPENBRACKET] = "Open Bracket"
- codes[KEY_CLOSEBRACKET] = "Close Bracket"
- codes[KEY_BACKSLASH] = "Backslash"
- codes[KEY_SEMICOLON] = "Semi-colon"
- codes[KEY_QUOTES] = "Quote"
- codes[KEY_COMMA] = "Comma"
- codes[KEY_PERIOD] = "Period"
- codes[KEY_SLASH] = "Slash"
-
- done=True
- EndIf
- End Function
-End Type
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.keysyms
+EndRem
+Module noddybox.keysyms
+
+ModuleInfo "Framework: English string symbols for keycodes"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.keycodes
+
+Rem
+bbdoc: Get a keysym.
+returns: The string name of @keycode, or "Unknown" for unknown codes.
+EndRem
+Function KeySym:String(keycode:Int)
+ KeySymStatic.Init()
+
+ If keycode<0 Or keycode>=KeySymStatic.codes.length
+ Return "Unknown"
+ EndIf
+
+ If KeySymStatic.codes[keycode]
+ Return KeySymStatic.codes[keycode]
+ Else
+ Return "Unknown"
+ EndIf
+End Function
+
+Private
+
+Type KeySymStatic
+ Global done:Int=False
+ Global codes:String[]
+
+ Function Init()
+ If Not done
+
+ ' TODO: This will break if keycodes are ever above 511
+ '
+ codes=New String[512]
+
+ codes[MOUSE_LEFT] = "Left Mouse button"
+ codes[MOUSE_RIGHT] = "Right Mouse button"
+ codes[MOUSE_MIDDLE] = "Middle Mouse button"
+ codes[KEY_BACKSPACE] = "Backspace"
+ codes[KEY_TAB] = "Tab"
+ codes[KEY_RETURN] = "Return"
+ codes[KEY_CLEAR] = "Clear"
+ codes[KEY_ENTER] = "Enter"
+ 'codes[KEY_PAUSE] = "Pause"
+ 'codes[KEY_CAPSLOCK] = "Caps Lock"
+ codes[KEY_ESCAPE] = "Escape"
+ codes[KEY_SPACE] = "Space"
+ codes[KEY_PAGEUP] = "Page Up"
+ codes[KEY_PAGEDOWN] = "Page Down"
+ codes[KEY_END] = "End"
+ codes[KEY_HOME] = "Home"
+ codes[KEY_LEFT] = "Left"
+ codes[KEY_UP] = "Up"
+ codes[KEY_RIGHT] = "Right"
+ codes[KEY_DOWN] = "Down"
+ codes[KEY_SELECT] = "Select"
+ codes[KEY_PRINT] = "Print"
+ codes[KEY_EXECUTE] = "Execute"
+ codes[KEY_SCREEN] = "Screen"
+ codes[KEY_INSERT] = "Insert"
+ codes[KEY_DELETE] = "Delete"
+ 'codes[KEY_HELP] = "Help"
+ codes[KEY_0] = "0"
+ codes[KEY_1] = "1"
+ codes[KEY_2] = "2"
+ codes[KEY_3] = "3"
+ codes[KEY_4] = "4"
+ codes[KEY_5] = "5"
+ codes[KEY_6] = "6"
+ codes[KEY_7] = "7"
+ codes[KEY_8] = "8"
+ codes[KEY_9] = "9"
+ codes[KEY_A] = "A"
+ codes[KEY_B] = "B"
+ codes[KEY_C] = "C"
+ codes[KEY_D] = "D"
+ codes[KEY_E] = "E"
+ codes[KEY_F] = "F"
+ codes[KEY_G] = "G"
+ codes[KEY_H] = "H"
+ codes[KEY_I] = "I"
+ codes[KEY_J] = "J"
+ codes[KEY_K] = "K"
+ codes[KEY_L] = "L"
+ codes[KEY_M] = "M"
+ codes[KEY_N] = "N"
+ codes[KEY_O] = "O"
+ codes[KEY_P] = "P"
+ codes[KEY_Q] = "Q"
+ codes[KEY_R] = "R"
+ codes[KEY_S] = "S"
+ codes[KEY_T] = "T"
+ codes[KEY_U] = "U"
+ codes[KEY_V] = "V"
+ codes[KEY_W] = "W"
+ codes[KEY_X] = "X"
+ codes[KEY_Y] = "Y"
+ codes[KEY_Z] = "Z"
+ codes[KEY_LSYS] = "Left Sys"
+ codes[KEY_RSYS] = "Right Sys"
+ codes[KEY_NUM0] = "Numpad 0"
+ codes[KEY_NUM1] = "Numpad 1"
+ codes[KEY_NUM2] = "Numpad 2"
+ codes[KEY_NUM3] = "Numpad 3"
+ codes[KEY_NUM4] = "Numpad 4"
+ codes[KEY_NUM5] = "Numpad 5"
+ codes[KEY_NUM6] = "Numpad 6"
+ codes[KEY_NUM7] = "Numpad 7"
+ codes[KEY_NUM8] = "Numpad 8"
+ codes[KEY_NUM9] = "Numpad 9"
+ codes[KEY_NUMMULTIPLY] = "Numpad *"
+ codes[KEY_NUMADD] = "Numpad +"
+ codes[KEY_NUMDIVIDE] = "Numpad /"
+ codes[KEY_NUMSUBTRACT] = "Numpad -"
+ codes[KEY_NUMDECIMAL] = "Numpad ."
+ codes[KEY_NUMDIVIDE] = "Numpad /"
+ codes[KEY_F1] = "F1"
+ codes[KEY_F2] = "F2"
+ codes[KEY_F3] = "F3"
+ codes[KEY_F4] = "F4"
+ codes[KEY_F5] = "F5"
+ codes[KEY_F6] = "F6"
+ codes[KEY_F7] = "F7"
+ codes[KEY_F8] = "F8"
+ codes[KEY_F9] = "F9"
+ codes[KEY_F10] = "F10"
+ codes[KEY_F11] = "F11"
+ codes[KEY_F12] = "F12"
+ 'codes[KEY_NUMLOCK] = "Num Lock"
+ 'codes[KEY_SCROLL] = "Scroll Lock"
+ codes[KEY_LSHIFT] = "Left Shift"
+ codes[KEY_RSHIFT] = "Right Shift"
+ codes[KEY_LCONTROL] = "Left Control"
+ codes[KEY_RCONTROL] = "Right Control"
+ codes[KEY_LALT] = "Left Alt"
+ codes[KEY_RALT] = "Right Alt"
+ codes[KEY_TILDE] = "Tilde"
+ codes[KEY_MINUS] = "Minus"
+ codes[KEY_EQUALS] = "Equals"
+ codes[KEY_OPENBRACKET] = "Open Bracket"
+ codes[KEY_CLOSEBRACKET] = "Close Bracket"
+ codes[KEY_BACKSLASH] = "Backslash"
+ codes[KEY_SEMICOLON] = "Semi-colon"
+ codes[KEY_QUOTES] = "Quote"
+ codes[KEY_COMMA] = "Comma"
+ codes[KEY_PERIOD] = "Period"
+ codes[KEY_SLASH] = "Slash"
+
+ done=True
+ EndIf
+ End Function
+End Type
diff --git a/mwidget.mod/mwidget.bmx b/mwidget.mod/mwidget.bmx
index 397d50d..51b2573 100644
--- a/mwidget.mod/mwidget.bmx
+++ b/mwidget.mod/mwidget.bmx
@@ -1,2808 +1,2807 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.mwidget
-about: <p>Provides a simply class based interface to the MaxGUI. Note that all widgets have create type methods. For these to work correctly with
-sub-classes they must be called through a new operation, e.g.</p>
-<pre>
-Type MyApp Extends TMWindow
-&nbsp;&nbsp;&nbsp;&nbsp;Method OnClose(e:TEvent)
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closed=Confirm("Really quit?")
-&nbsp;&nbsp;&nbsp;&nbsp;End Method
-End Type
-
-Local window:TMWindow=New MyApp.Create("Test",100,100,640,400)
-MWidgetMainLoop(window)
-</pre>
-<p>
-There are two methods of getting events. One is to subclass and override the events, as with the @OnClose() above. The other is to set
-function pointers in the matching event lists, @OnCloseEvent in this instance. For instance:
-</p>
-<pre>
-Function OnClose(o:TMWidget)
-&nbsp;&nbsp;&nbsp;&nbsp;Local w:TMWindow=TMWindow(o)
-&nbsp;&nbsp;&nbsp;&nbsp;w.closed=Confirm("Really quit?")
-End Function
-
-Local window:TMWindow=New TMWindow.Create("Test",100,100,640,400)
-window.OnCloseEvent.Add(OnClose)
-MWidgetMainLoop(window)
-</pre>
-<p>
-When using the function callback method of capturing events, the parameters to the function are the same as the overridable method with the addition
-of the managed widget which is passed in as the first argument.
-</p>
-EndRem
-Module noddybox.mwidget
-
-ModuleInfo "Framework: Simple Managed Widget Classes"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-Import maxgui.maxgui
-Import brl.linkedlist
-Import brl.event
-Import brl.timer
-Import brl.map
-Import brl.filesystem
-Import brl.eventqueue
-
-Type TMWEventListBase Abstract
- Field list:TList
- Method New()
- list=CreateList()
- End Method
-End Type
-
-Type TMWFuncVoid
- Field func(w:TMWidget)
- Function Create:TMWFuncVoid(func(w:TMWidget))
- Local o:TMWFuncVoid=New TMWFuncVoid
- o.func=func
- Return o
- End Function
-End Type
-
-Type TMWFuncInt
- Field func(w:TMWidget, a:Int)
- Function Create:TMWFuncInt(func(w:TMWidget, a:Int))
- Local o:TMWFuncInt=New TMWFuncInt
- o.func=func
- Return o
- End Function
-End Type
-
-Type TMWFuncIntInt
- Field func(w:TMWidget, a:Int, b:Int)
- Function Create:TMWFuncIntInt(func(w:TMWidget, a:Int, b:Int))
- Local o:TMWFuncIntInt=New TMWFuncIntInt
- o.func=func
- Return o
- End Function
-End Type
-
-Type TMWFuncString
- Field func(w:TMWidget, a:String)
- Function Create:TMWFuncString(func(w:TMWidget, a:String))
- Local o:TMWFuncString=New TMWFuncString
- o.func=func
- Return o
- End Function
-End Type
-
-
-Type TMWFuncStringObject
- Field func(w:TMWidget, a:String, b:Object)
- Function Create:TMWFuncStringObject(func(w:TMWidget, a:String, b:Object))
- Local o:TMWFuncStringObject=New TMWFuncStringObject
- o.func=func
- Return o
- End Function
-End Type
-
-
-Rem
-bbdoc: Defines an event list for functions that take the parameters (w:TMWidget)
-EndRem
-Type TMWEventListVoid Extends TMWEventListBase Final
- Rem
- bbdoc: Adds a callback function.
- EndRem
- Method Add(func(w:TMWidget))
- list.AddLast(TMWFuncVoid.Create(func))
- End Method
-
- Rem
- bbdoc: Clears all callback functions.
- EndRem
- Method Clear()
- list.Clear()
- End Method
-
- Rem
- bbdoc: Removes a callback function.
- EndRem
- Method Remove(func(w:TMWidget))
- For Local fp:TMWFuncVoid=EachIn list
- If fp.func=func
- list.Remove(fp)
- Return
- EndIf
- Next
- End Method
-
- Method Fire(w:TMWidget)
- For Local fp:TMWFuncVoid=EachIn list
- fp.func(w)
- Next
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:Int)
-EndRem
-Type TMWEventListInt Extends TMWEventListBase Final
- Rem
- bbdoc: Adds a callback function.
- EndRem
- Method Add(func(w:TMWidget, a:Int))
- list.AddLast(TMWFuncInt.Create(func))
- End Method
-
- Rem
- bbdoc: Clears all callback functions.
- EndRem
- Method Clear()
- list.Clear()
- End Method
-
- Rem
- bbdoc: Removes a callback function.
- EndRem
- Method Remove(func(w:TMWidget, a:Int))
- For Local fp:TMWFuncInt=EachIn list
- If fp.func=func
- list.Remove(fp)
- Return
- EndIf
- Next
- End Method
-
- Method Fire(w:TMWidget, a:Int)
- For Local fp:TMWFuncInt=EachIn list
- fp.func(w,a)
- Next
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:String)
-EndRem
-Type TMWEventListString Extends TMWEventListBase Final
- Rem
- bbdoc: Adds a callback function.
- EndRem
- Method Add(func(w:TMWidget, a:String))
- list.AddLast(TMWFuncString.Create(func))
- End Method
-
- Rem
- bbdoc: Clears all callback functions.
- EndRem
- Method Clear()
- list.Clear()
- End Method
-
- Rem
- bbdoc: Removes a callback function.
- EndRem
- Method Remove(func(w:TMWidget, a:String))
- For Local fp:TMWFuncString=EachIn list
- If fp.func=func
- list.Remove(fp)
- Return
- EndIf
- Next
- End Method
-
- Method Fire(w:TMWidget, a:String)
- For Local fp:TMWFuncString=EachIn list
- fp.func(w,a)
- Next
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:Int, b:Int)
-EndRem
-Type TMWEventListIntInt Extends TMWEventListBase Final
- Rem
- bbdoc: Adds a callback function.
- EndRem
- Method Add(func(w:TMWidget, a:Int, b:Int))
- list.AddLast(TMWFuncIntInt.Create(func))
- End Method
-
- Rem
- bbdoc: Clears all callback functions.
- EndRem
- Method Clear()
- list.Clear()
- End Method
-
- Rem
- bbdoc: Removes a callback function.
- EndRem
- Method Remove(func(w:TMWidget, a:Int, b:Int))
- For Local fp:TMWFuncIntInt=EachIn list
- If fp.func=func
- list.Remove(fp)
- Return
- EndIf
- Next
- End Method
-
- Method Fire(w:TMWidget, a:Int, b:Int)
- For Local fp:TMWFuncIntInt=EachIn list
- fp.func(w,a,b)
- Next
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:String, b:Object)
-EndRem
-Type TMWEventListStringObject Extends TMWEventListBase Final
- Rem
- bbdoc: Adds a callback function.
- EndRem
- Method Add(func(w:TMWidget, a:String, b:Object))
- list.AddLast(TMWFuncStringObject.Create(func))
- End Method
-
- Rem
- bbdoc: Clears all callback functions.
- EndRem
- Method Clear()
- list.Clear()
- End Method
-
- Rem
- bbdoc: Removes a callback function.
- EndRem
- Method Remove(func(w:TMWidget, a:String, b:Object))
- For Local fp:TMWFuncStringObject=EachIn list
- If fp.func=func
- list.Remove(fp)
- Return
- EndIf
- Next
- End Method
-
- Method Fire(w:TMWidget, a:String, b:Object)
- For Local fp:TMWFuncStringObject=EachIn list
- fp.func(w,a,b)
- Next
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a base managed widget type.
-EndRem
-Type TMWidget Abstract
-
- Rem
- bbdoc: The underlying BlitzMAX GUI Gadget
- EndRem
- Field gadget:TGadget
-
- Rem
- bbdoc: The parent of this managed widget
- EndRem
- Field parent:TMWidget
-
- Rem
- bbdoc: Children of this managed widget
- EndRem
- Field children:TList
-
- Field typename:String
- Field timer:TTimer
-
- Method Delete()
- FreeGadget(gadget)
- End Method
-
- Rem
- bbdoc: Handles an event.
- about: Sub-classes will generally override this to handle events directed at themselves.
- If the event is unhandled then the event should be passed up to the parent type. @e holds the TEvent.
- EndRem
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_MOUSEENTER
- OnMouseEnter()
- OnMouseEnterEvent.Fire(Self)
- Case EVENT_MOUSELEAVE
- OnMouseLeave()
- OnMouseLeaveEvent.Fire(Self)
- Case EVENT_TIMERTICK
- OnTimer()
- OnTimerEvent.Fire(Self)
- End Select
- End Method
-
- Rem
- bbdoc: Activate the widget (give it keyboard focus).
- EndRem
- Method Activate(state:Int)
- ActivateGadget(gadget)
- End Method
-
- Rem
- bbdoc: Enables/disables a widget.
- EndRem
- Method Enabled(state:Int)
- If state
- EnableGadget(gadget)
- Else
- DisableGadget(gadget)
- EndIf
- End Method
-
- Rem
- bbdoc: Is widget enabled.
- returns: TRUE if enabled.
- EndRem
- Method IsEnabled:Int()
- Return Not GadgetDisabled(gadget)
- End Method
-
- Rem
- bbdoc: Hide/show the widget.
- EndRem
- Method Hidden(state:Int)
- If state
- HideGadget(gadget)
- Else
- ShowGadget(gadget)
- EndIf
- End Method
-
- Rem
- bbdoc: Is widget hidden.
- returns: TRUE if hidden.
- EndRem
- Method IsHidden:Int()
- Return GadgetHidden(gadget)
- End Method
-
- Rem
- bbdoc: The widget's position.
- returns: The widget's X co-ordinate.
- EndRem
- Method X:Int()
- Return GadgetX(gadget)
- End Method
-
- Rem
- bbdoc: The widget's position.
- returns: The widget's Y co-ordinate.
- EndRem
- Method Y:Int()
- Return GadgetY(gadget)
- End Method
-
- Rem
- bbdoc: The widget's size.
- returns: The widget's width.
- EndRem
- Method Width:Int()
- Return GadgetWidth(gadget)
- End Method
-
- Rem
- bbdoc: The widget's size.
- returns: The widget's height.
- EndRem
- Method Height:Int()
- Return GadgetHeight(gadget)
- End Method
-
- Rem
- bbdoc: The widget's client size.
- returns: The widget's client width.
- EndRem
- Method Client_Width:Int()
- Return ClientWidth(gadget)
- End Method
-
- Rem
- bbdoc: The widget's client size.
- returns: The widget's client height.
- EndRem
- Method Client_Height:Int()
- Return ClientHeight(gadget)
- End Method
-
- Rem
- bbdoc: Set the widget's font.
- EndRem
- Method Font(font:TGUIFont)
- SetGadgetFont(gadget,font)
- End Method
-
- Rem
- bbdoc: Set the widgets's layout. See Max GUIs SetGadgetLayout() for details.
- EndRem
- Method Layout(Left:Int, Right:Int, top:Int, bottom:Int)
- SetGadgetLayout(gadget,Left,Right,top,bottom)
- End Method
-
- Rem
- bbdoc: Set the widget's position and size.
- EndRem
- Method SetShape(x:Int, y:Int, width:Int, height:Int)
- SetGadgetShape(gadget,x,y,width,height)
- End Method
-
- Rem
- bbdoc: Set the widgets's alpha.
- EndRem
- Method Alpha(a:Double)
- SetGadgetAlpha(gadget,a)
- End Method
-
- Rem
- bbdoc: Set the widgets's text colour.
- EndRem
- Method TextColour(r:Int, g:Int, b:Int)
- SetGadgetTextColor(gadget,r,g,b)
- End Method
-
- Rem
- bbdoc: Set the widgets's background colour.
- EndRem
- Method BackColour(r:Int, g:Int, b:Int)
- SetGadgetColor(gadget,r,g,b)
- End Method
-
- Rem
- bbdoc: Set the widgets's text.
- EndRem
- Method Text(s:String)
- SetGadgetText(gadget,s)
- End Method
-
- Rem
- bbdoc: Print the widget
- EndRem
- Method Print()
- GadgetPrint(gadget)
- End Method
-
- Rem
- bbdoc: Perform a cut on the widget
- EndRem
- Method Cut()
- GadgetCut(gadget)
- End Method
-
- Rem
- bbdoc: Perform a copy on the widget
- EndRem
- Method Copy()
- GadgetCopy(gadget)
- End Method
-
- Rem
- bbdoc: Perform a paste on the widget
- EndRem
- Method Paste()
- GadgetPaste(gadget)
- End Method
-
- Rem
- bbdoc: Allocates a timer for this widget.
- about: Create a Blitz MAX TTimer that is fired @hertz times a second. When the timer pulses then @OnTimer() is called.
- If this routine is called when a timer is already active, then the timer is re-initialised with the passed hertz.
- EndRem
- Method SetTimer(hertz:Double)
- ClearTimer()
- timer=CreateTimer(hertz,CreateEvent(EVENT_TIMERTICK,gadget))
- End Method
-
- Rem
- bbdoc: Clears timer previously activated by @SetTimer().
- EndRem
- Method ClearTimer()
- If timer
- StopTimer(timer)
- EndIf
- timer=Null
- End Method
-
- Rem
- bbdoc: Called when the widget's timer fires.
- EndRem
- Method OnTimer()
- End Method
-
- Rem
- bbdoc: Called when the widget's timer fires.
- EndRem
- Field OnTimerEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the widget is managed.
- EndRem
- Method OnManage()
- End Method
-
- Rem
- bbdoc: Called when the widget is managed.
- EndRem
- Field OnManageEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the widget is unmanaged.
- EndRem
- Method OnUnmanage()
- End Method
-
- Rem
- bbdoc: Called when the widget is unmanaged.
- EndRem
- Field OnUnmanageEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the mouse enters.
- EndRem
- Method OnMouseEnter()
- End Method
-
- Rem
- bbdoc: Called when the mouse enters.
- EndRem
- Field OnMouseEnterEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the mouse leaves.
- EndRem
- Method OnMouseLeave()
- End Method
-
- Rem
- bbdoc: Called when the mouse leaves.
- EndRem
- Field OnMouseLeaveEvent:TMWEventListVoid
-
- Rem
- bbdoc: Fires an event at this managed widget.
- about: The arguments are the same as @CreateEvent(), but no source is passed in.
- EndRem
- Method Emit(id:Int, data:Int=0, mods:Int=0, x:Int=0, y:Int=0,extra:Object=Null)
- EmitEvent(CreateEvent(id,gadget,data,mods,x,y,extra))
- End Method
-
- Rem
- bbdoc: Initialises the base managed widget stuff.
- about: All sub-classes must call this! @gadget is the created TGadget for this instance,
- and @parent is the parent managed widget (NULL for none).
- EndRem
- Method BaseInitialise(gadget:TGadget, parent:TMWidget)
- Self.children=CreateList()
- Self.gadget=gadget
- Self.parent=parent
-
- OnTimerEvent=New TMWEventListVoid
- OnManageEvent=New TMWEventListVoid
- OnUnmanageEvent=New TMWEventListVoid
- OnMouseEnterEvent=New TMWEventListVoid
- OnMouseLeaveEvent=New TMWEventListVoid
-
- If Self.parent
- Self.parent.children.AddLast(Self)
- EndIf
-
- Static.Register(Self)
- End Method
-
- Rem
- bbdoc: Removes the managed widget from the internal lists.
- about: All child objects will also be unmanaged.
- EndRem
- Method Unmanage()
- Static.Deregister(Self)
- End Method
-
- Method ToString:String()
- Return typename+":"+Super.ToString()
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed window.
-EndRem
-Type TMWindow Extends TMWidget
-
- Rem
- bbdoc: Creates a managed window.
- returns: The created window.
- about: @name, @x, @y, @w, @h, @group and @flags act the same as the MaxGUI arguments to @CreateWindow(), except that @group is a TMWidget.
- EndRem
- Method Create:TMWindow(name:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget=Null, flags:Int=15)
- closed=False
-
- OnMoveEvent=New TMWEventListIntInt
- OnResizeEvent=New TMWEventListIntInt
- OnCloseEvent=New TMWEventListVoid
- OnDropEvent=New TMWEventListString
-
- Local g:TGadget
-
- If group
- g=CreateWindow(name,x,y,w,h,group.gadget,flags)
- Else
- g=CreateWindow(name,x,y,w,h,Null,flags)
- EndIf
-
- BaseInitialise(g,group)
- typename="TMWindow"
- Return Self
- End Method
-
- Rem
- bbdoc: Set to TRUE when the window is closed (the user has pressed the close gadget).
- EndRem
- Field closed:Int
-
- Rem
- bbdoc: Activate the window.
- EndRem
- Method Activate(state:Int)
- ActivateWindow(gadget)
- End Method
-
- Rem
- bbdoc: Send a close event to this window.
- EndRem
- Method Close()
- Emit(EVENT_WINDOWCLOSE)
- End Method
-
- Rem
- bbdoc: Hide to show the window.
- about: Note that this sets the @closed field to the @state passed in.
- EndRem
- Method Hidden(state:Int)
- closed=state
- Super.Hidden(state)
- End Method
-
- Rem
- bbdoc: Set the window's status text.
- EndRem
- Method StatusText(text:String)
- SetStatusText(gadget,text)
- End Method
-
- Rem
- bbdoc: Set the window's minimum size.
- EndRem
- Method MinSize(width:Int, height:Int)
- Return SetMinWindowSize(gadget,width,height)
- End Method
-
- Rem
- bbdoc: Restore a minimizwed or maximized window.
- EndRem
- Method Restore()
- Return RestoreWindow(gadget)
- End Method
-
- Rem
- bbdoc: Maximize the window.
- EndRem
- Method Maximize()
- Return MaximizeWindow(gadget)
- End Method
-
- Rem
- bbdoc: Is the window maximized?
- returns:TRUE if the window is maximized
- EndRem
- Method IsMaximized()
- Return WindowMaximized(gadget)
- End Method
-
- Rem
- bbdoc: Minimize the window.
- EndRem
- Method Minimize()
- Return MinimizeWindow(gadget)
- End Method
-
- Rem
- bbdoc: Is the window minimized?
- returns:TRUE if the window is minimized
- EndRem
- Method IsMinimized()
- Return WindowMinimized(gadget)
- End Method
-
- Rem
- bbdoc: Called when the window is moved.
- about:@x and @y are the new position.
- EndRem
- Method OnMove(x:Int, y:Int)
- End Method
-
- Rem
- bbdoc: Called when the window is moved.
- EndRem
- Field OnMoveEvent:TMWEventListIntInt
-
- Rem
- bbdoc: Called when the window is resized.
- about:@width and @height are the new size.
- EndRem
- Method OnResize(width:Int, height:Int)
- End Method
-
- Rem
- bbdoc: Called when the window is resized.
- EndRem
- Field OnResizeEvent:TMWEventListIntInt
-
- Rem
- bbdoc: Called when the window's close gadget is pressed.
- about: This default implementation sets @closed to TRUE and hide the window if no events are defined in @OnCloseEvent.
- EndRem
- Method OnClose()
- If Not OnCloseEvent.list.Count()
- closed=True
- Hidden(True)
- EndIf
- End Method
-
- Rem
- bbdoc: Called when the window's close gadget is pressed.
- EndRem
- Field OnCloseEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when a file is dropped in the window.
- about: @path is the dropped file.
- EndRem
- Method OnDrop(path:String)
- End Method
-
- Rem
- bbdoc: Called when a file is dropped in the window.
- EndRem
- Field OnDropEvent:TMWEventListString
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_WINDOWACCEPT
- OnDrop(String(e.extra))
- OnDropEvent.Fire(Self,String(e.extra))
- Case EVENT_WINDOWMOVE
- OnMove(e.x,e.y)
- OnMoveEvent.Fire(Self,e.x,e.y)
- Case EVENT_WINDOWSIZE
- OnResize(e.x,e.y)
- OnResizeEvent.Fire(Self,e.x,e.y)
- Case EVENT_WINDOWCLOSE
- OnClose()
- OnCloseEvent.Fire(Self)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed button push button.
-EndRem
-Type TMButton Extends TMWidget
-
- Rem
- bbdoc: Creates a managed push button.
- returns: The created button.
- about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
- EndRem
- Method Create:TMButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- OnPressEvent=New TMWEventListVoid
- BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_PUSH),group)
- typename="TMButton"
- Return Self
- End Method
-
- Rem
- bbdoc: Creates a managed push button used for an OK button
- returns: The created button.
- about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
- EndRem
- Method CreateOK:TMButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- OnPressEvent=New TMWEventListVoid
- BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_OK),group)
- typename="TMButton"
- Return Self
- End Method
-
- Rem
- bbdoc: Creates a managed push button used for a Cancel button
- returns: The created button.
- about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
- EndRem
- Method CreateCancel:TMButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- OnPressEvent=New TMWEventListVoid
- BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_OK),group)
- typename="TMButton"
- Return Self
- End Method
-
- Rem
- bbdoc: Called when the button is pressed.
- EndRem
- Method OnPress()
- End Method
-
- Rem
- bbdoc: Called when the button is pressed.
- EndRem
- Field OnPressEvent:TMWEventListVoid
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnPress()
- OnPressEvent.Fire(Self)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed checkbox.
-EndRem
-Type TMCheckbox Extends TMWidget
- Rem
- bbdoc: Creates a managed checkbox.
- returns: The created checkbox.
- about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
- EndRem
- Method Create:TMCheckbox(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- OnPressEvent=New TMWEventListInt
- BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_CHECKBOX),group)
- typename="TMCheckbox"
- Return Self
- End Method
-
- Rem
- bbdoc: Sets the state of the check.
- EndRem
- Method Checked(check:Int)
- SetButtonState(gadget,check)
- End Method
-
- Rem
- bbdoc: Is the checkbox checked?
- returns:TRUE if the checkbox is checked.
- EndRem
- Method IsChecked()
- Return ButtonState(gadget)
- End Method
-
- Rem
- bbdoc: Called when the checkbox is pressed.
- about: @checked is the current state.
- EndRem
- Method OnPress(checked:Int)
- End Method
-
- Rem
- bbdoc: Called when the checkbox is pressed.
- EndRem
- Field OnPressEvent:TMWEventListInt
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnPress(e.data)
- OnPressEvent.Fire(Self,e.data)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed radio button.
-EndRem
-Type TMRadioButton Extends TMCheckbox
- Field set:TMRadioButtonSet
-
- Rem
- bbdoc: Creates a managed radio button.
- returns: The created radio button.
- about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
- EndRem
- Method Create:TMRadioButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- OnPressEvent=New TMWEventListInt
- BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_RADIO),group)
- typename="TMRadioButton"
- Return Self
- End Method
-
- Rem
- bbdoc: Called when the checkbox is pressed.
- about: @checked is the current state. In this default implementation the @TMRadioButtonSet which this button belongs too will fire
- its @OnSelected() member.
- EndRem
- Method OnPress(checked:Int)
- If set
- set.ButtonFired(Self)
- EndIf
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a set of managed radio button.
-EndRem
-Type TMRadioButtonSet
- Field but:TMRadioButton[]
-
- Rem
- bbdoc: Creates a set of managed radio buttons.
- returns: The created set.
- about: The radio buttons must have been created prior to calling this.
- EndRem
- Method Create:TMRadioButtonSet(buttons:TMRadioButton[])
- OnSelectedEvent=New TMWEventListInt
- but=buttons
- For Local b:TMRadioButton=EachIn but
- b.set=Self
- Next
- Return Self
- End Method
-
- Rem
- bbdoc: Sets the active radio button.
- about: @index is the index of the button to set.
- EndRem
- Method Set(index:Int)
- but[index].Checked(True)
- End Method
-
- Rem
- bbdoc: If using the base TMRadioButton implmentation this will be called when the buttons change.
- about: @index is the selected button.
- EndRem
- Method OnSelected(index:Int)
- End Method
-
- Rem
- bbdoc: If using the base TMRadioButton implmentation this will be called when the buttons change.
- about: The radio button that fired will be passed into the event.
- EndRem
- Field OnSelectedEvent:TMWEventListInt
-
- Rem
- bbdoc: Get the active radio button.
- returns: The index of the button set. -1 if no button is set.
- EndRem
- Method Current()
- For Local f:Int=0 Until but.length
- If but[f].IsChecked()
- Return f
- EndIf
- Next
- Return -1
- End Method
-
- Method ButtonFired(b:TMRadioButton)
- For Local f:Int=0 Until but.length
- If but[f]=b
- OnSelected(f)
- OnSelectedEvent.Fire(b,f)
- Return
- EndIf
- Next
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed label.
-EndRem
-Type TMLabel Extends TMWidget
-
- Rem
- bbdoc: Creates a managed label.
- returns: The created label.
- about: @label, @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateLabel(), except that @group is a TMWidget.
- EndRem
- Method Create:TMLabel(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- BaseInitialise(CreateLabel(label,x,y,w,h,group.gadget,style),group)
- typename="TMLabel"
- Return Self
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed text field.
-EndRem
-Type TMTextField Extends TMWidget
- Rem
- bbdoc: Creates a managed text field.
- returns: The created text field.
- about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateTextField(), except that @group is a TMWidget.
- EndRem
- Method Create:TMTextField(x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- OnTextChangedEvent=New TMWEventListString
- BaseInitialise(CreateTextField(x,y,w,h,group.gadget),group)
- typename="TMTextField"
- Return Self
- End Method
-
- Rem
- bbdoc: Creates a managed text field for entering passwords.
- returns: The created text field.
- about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateTextField(), except that @group is a TMWidget.
- EndRem
- Method CreateSecret:TMTextField(x:Int,y:Int, w:Int, h:Int, group:TMWidget)
- BaseInitialise(CreateTextField(x,y,w,h,group.gadget,TEXTFIELD_PASSWORD),group)
- typename="TMTextField"
- Return Self
- End Method
-
- Rem
- bbdoc: The field's text.
- returns:The text.
- EndRem
- Method GetText:String()
- Return TextFieldText(gadget)
- End Method
-
- Rem
- bbdoc: Called when the text changes.
- about: @txt is the content of the field
- EndRem
- Method OnTextChanged(txt:String)
- End Method
-
- Rem
- bbdoc: Called when the text changes.
- EndRem
- Field OnTextChangedEvent:TMWEventListString
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- Local s:String=TextFieldText(gadget)
- OnTextChanged(s)
- OnTextChangedEvent.Fire(Self,s)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed text area.
-EndRem
-Type TMTextArea Extends TMWidget
- Rem
- bbdoc: Creates a managed text area.
- returns: The created text area.
- about: @x, @y, @w, @h,, @group and @style act the same as the MaxGUI arguments to @CreateTextArea(), except that @group is a TMWidget.
- EndRem
- Method Create:TMTextArea(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- OnTextChangedEvent=New TMWEventListVoid
- OnSelectionEvent=New TMWEventListVoid
- OnMenuEvent=New TMWEventListVoid
- BaseInitialise(CreateTextArea(x,y,w,h,group.gadget,style),group)
- typename="TMTextArea"
- Return Self
- End Method
-
- Rem
- bbdoc: The text area's text.
- returns:The text.
- EndRem
- Method GetText:String(pos:Int=0, length:Int=TEXTAREA_ALL, units:Int=TEXTAREA_CHARS)
- Return TextAreaText(gadget,pos,length,units)
- End Method
-
- Rem
- bbdoc: Set the widget's font.
- EndRem
- Method Font(font:TGUIFont)
- SetTextAreaFont(gadget,font)
- End Method
-
- Rem
- bbdoc: Set the widgets's text colour.
- EndRem
- Method TextColour(r:Int, g:Int, b:Int)
- SetTextAreaColor(gadget,r,g,b,False)
- End Method
-
- Rem
- bbdoc: Set the widgets's background colour.
- EndRem
- Method BackColour(r:Int, g:Int, b:Int)
- SetTextAreaColor(gadget,r,g,b,True)
- End Method
-
- Rem
- bbdoc: Set the widgets's text.
- EndRem
- Method Text(s:String)
- SetText(s)
- End Method
-
- Rem
- bbdoc: Set the widgets's text (see the MaxGUI docs for argument details)
- EndRem
- Method SetText(s:String, pos:Int=0, length:Int=TEXTAREA_ALL, units:Int=TEXTAREA_CHARS)
- SetTextAreaText(gadget,s,pos,length,units)
- End Method
-
- Rem
- bbdoc: Set the text area's tab size
- EndRem
- Method SetTabSize(size:Int)
- SetTextAreaTabs(gadget,size)
- End Method
-
- Rem
- bbdoc: Get the character position of the specified line.
- EndRem
- Method GetCharPos:Int(line:Int)
- Return TextAreaChar(gadget,line)
- End Method
-
- Rem
- bbdoc: Get the cursor's column.
- EndRem
- Method GetCursorColumn:Int()
- Return TextAreaCursor(gadget,TEXTAREA_CHARS)
- End Method
-
- Rem
- bbdoc: Get the cursor's row.
- EndRem
- Method GetCursorRow:Int()
- Return TextAreaCursor(gadget,TEXTAREA_LINES)
- End Method
-
- Rem
- bbdoc: Get the text length.
- EndRem
- Method GetLength:Int()
- Return TextAreaLen(gadget)
- End Method
-
- Rem
- bbdoc: Get the selected texts length.
- EndRem
- Method GetSelectionLength:Int()
- Return TextAreaSelLen(gadget,TEXTAREA_CHARS)
- End Method
-
- Rem
- bbdoc: Get the number of selected rows.
- EndRem
- Method GetSelectionRows:Int()
- Return TextAreaSelLen(gadget,TEXTAREA_LINES)
- End Method
-
- Rem
- bbdoc: Lock the text area.
- EndRem
- Method Lock()
- Return LockTextArea(gadget)
- End Method
-
- Rem
- bbdoc: Unlock the text area.
- EndRem
- Method Unlock()
- Return UnlockTextArea(gadget)
- End Method
-
- Rem
- bbdoc: Set the format. See the MaxGUI docs for details.
- EndRem
- Method Format(r:Int, g:Int, b:Int, flags:Int, pos:Int=0, length:Int=TEXTAREA_ALL, units:Int=TEXTAREA_CHARS )
- FormatTextAreaText(gadget,r,g,b,flags,pos,length,units)
- End Method
-
- Rem
- bbdoc: Called when the text changes.
- EndRem
- Method OnTextChanged()
- End Method
-
- Rem
- bbdoc: Called when the text changes.
- EndRem
- Field OnTextChangedEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the selection or cursor changes.
- EndRem
- Method OnSelection()
- End Method
-
- Rem
- bbdoc: Called when the selection or cursor changes.
- EndRem
- Field OnSelectionEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the context menu is requested.
- EndRem
- Method OnMenu()
- End Method
-
- Rem
- bbdoc: Called when the context menu is requested.
- EndRem
- Field OnMenuEvent:TMWEventListVoid
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnTextChanged()
- OnTextChangedEvent.Fire(Self)
- Case EVENT_GADGETSELECT
- OnSelection()
- OnSelectionEvent.Fire(Self)
- Case EVENT_GADGETMENU
- OnMenu()
- OnMenuEvent.Fire(Self)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed slider.
-EndRem
-Type TMSlider Extends TMWidget
- Rem
- bbdoc: Creates a managed slider.
- returns: The created slider.
- about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateSlider(), except that @group is a TMWidget.
- EndRem
- Method Create:TMSlider(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- OnValueChangedEvent=New TMWEventListInt
- BaseInitialise(CreateSlider(x,y,w,h,group.gadget,style),group)
- typename="TMSlider"
- Return Self
- End Method
-
- Rem
- bbdoc: Set the sliders's min/max values.
- about: See the MaxGUI docs for how this affects scrollbar style sliders.
- EndRem
- Method SetRange(range0:Int,range1:Int)
- Return SetSliderRange(gadget,range0,range1)
- End Method
-
- Rem
- bbdoc: Set the sliders's value.
- EndRem
- Method SetValue(value:Int)
- Return SetSliderValue(gadget,value)
- End Method
-
- Rem
- bbdoc: The sliders's value.
- returns:The value.
- EndRem
- Method GetValue:Int()
- Return SliderValue(gadget)
- End Method
-
- Rem
- bbdoc: Called when the slider moves.
- about: @val is the new slider value.
- EndRem
- Method OnValueChanged(val:Int)
- End Method
-
- Rem
- bbdoc: Called when the slider moves.
- EndRem
- Field OnValueChangedEvent:TMWEventListInt
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnValueChanged(e.data)
- OnValueChangedEvent.Fire(Self,e.data)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines an entry in a list style gadget.
-about: Always use @CreateListEntry() to create this object.
-EndRem
-Type TMListEntry
- Rem
- bbdoc: The text associated with a list entry.
- EndRem
- Field text:String
- Rem
- bbdoc: The flags associated with a list entry.
- EndRem
- Field flags:Int
- Rem
- bbdoc: The icon associated with a list entry.
- EndRem
- Field icon:Int
- Rem
- bbdoc: The tooltip associated with a list entry.
- EndRem
- Field tip:String
- Rem
- bbdoc: The extra object associated with a list entry.
- EndRem
- Field extra:Object
-
- Function Create:TMListEntry(text:String,flags:Int,icon:Int,tip:String,extra:Object)
- Local o:TMListEntry=New TMListEntry
- o.text=text
- o.flags=flags
- o.icon=icon
- o.tip=tip
- o.extra=extra
- Return o
- End Function
-End Type
-
-
-Rem
-bbdoc: Creates a list entry.
-returns: The list entry.
-about: @text, @flags, @icon, @tip and @extra are the fields detailed in MaxGUI @AddGadgetItem().
-EndRem
-Function CreateListEntry:TMListEntry(text:String,flags:Int=0,icon:Int=-1,tip:String="",extra:Object=Null)
- Return TMListEntry.Create(text,flags,icon,tip,extra)
-End Function
-
-
-Rem
-bbdoc: Defines a base for list style gadgets.
-EndRem
-Type TMListWidget Extends TMWidget Abstract
- Rem
- bbdoc: Removes all items from the list.
- EndRem
- Method Clear()
- ClearGadgetItems(gadget)
- End Method
-
- Rem
- bbdoc: Adds an item to the list.
- EndRem
- Method AddItem(entry:TMListEntry)
- AddGadgetItem(gadget,entry.text,entry.flags,entry.icon,entry.tip,entry.extra)
- End Method
-
- Rem
- bbdoc: Adds items to the list.
- EndRem
- Method AddItems(entry:TMListEntry[])
- For Local f:Int=0 Until entry.length
- AddItem(entry[f])
- Next
- End Method
-
- Rem
- bbdoc: Modify an item in the list.
- EndRem
- Method ModifyItem(index:Int, entry:TMListEntry)
- ModifyGadgetItem(gadget,index,entry.text,entry.flags,entry.icon,entry.tip,entry.extra)
- End Method
-
- Rem
- bbdoc: Set an icon strip for the list.
- EndRem
- Method SetIconStrip(icons:TIconStrip)
- SetGadgetIconStrip(gadget,icons)
- End Method
-
- Rem
- bbdoc: Get an item from the list.
- about: Note that the @tip field is not set on return
- EndRem
- Method GetItem:TMListEntry(index:Int)
- Return CreateListEntry(GadgetItemText(gadget,index), ..
- GadgetItemFlags(gadget,index), ..
- GadgetItemIcon(gadget,index), ..
- "", ..
- GadgetItemExtra(gadget,index))
- End Method
-
- Rem
- bbdoc: Enable or disable a particular item.
- EndRem
- Method ItemEnabled(index:Int, state:Int)
- If state
- EnableGadgetItem(gadget,index)
- Else
- DisableGadgetItem(gadget,index)
- EndIf
- End Method
-
- Rem
- bbdoc: Set the currently selected item.
- EndRem
- Method SetSelectedIndex(index:Int)
- SelectGadgetItem(gadget,index)
- End Method
-
- Rem
- bbdoc: Get the index of the first selected item.
- EndRem
- Method SelectedIndex:Int()
- Return SelectedGadgetItem(gadget)
- End Method
-
- Rem
- bbdoc: Get the indexes of the selected items.
- EndRem
- Method SelectedIndexes:Int[]()
- Return SelectedGadgetItems(gadget)
- End Method
-
- Rem
- bbdoc: Get the first selected item, NULL if nothing selected.
- EndRem
- Method SelectedItem:TMListEntry()
- If SelectedIndex()=-1
- Return Null
- EndIf
-
- Return GetItem(SelectedIndex())
- End Method
-
- Rem
- bbdoc: Get the selected items, NULL if nothing selected.
- EndRem
- Method SelectedItems:TMListEntry[]()
- If SelectedIndex()=-1
- Return Null
- EndIf
-
- Local sel:Int[]=SelectedIndexes()
- Local ret:TMListEntry[]=New TMListEntry[sel.length]
-
- For Local f:Int=0 Until sel.length
- ret[f]=GetItem(sel[f])
- Next
- Return ret
- End Method
-
- Rem
- bbdoc: Called when the selection changes.
- about: @index is the selected index. This can be -1 for no selection.
- EndRem
- Method OnIndexChanged(index:Int)
- End Method
-
- Rem
- bbdoc: Called when the selection changes.
- EndRem
- Field OnIndexChangedEvent:TMWEventListInt
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnIndexChanged(e.data)
- OnIndexChangedEvent.Fire(Self,e.data)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed combo box.
-EndRem
-Type TMComboBox Extends TMListWidget
- Rem
- bbdoc: Creates a managed combo box.
- returns: The created combo box.
- about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateComboBox(), except that @group is a TMWidget.
- If @values is not NULL it is used to load up the initial options.
- <b>IMPORTANT</b>: It is really not recommended to use COMBOBOX_EDITABLE as OnIndexChanged() is called when the user edits the field.
- There seems to be no easy way to remedy this.
- EndRem
- Method Create:TMComboBox(x:Int,y:Int, w:Int, h:Int, group:TMWidget, style:Int=0, values:TMListEntry[]=Null)
- OnIndexChangedEvent=New TMWEventListInt
- BaseInitialise(CreateComboBox(x,y,w,h,group.gadget,style),group)
- typename="TMComboBox"
- If values
- AddItems(values)
- EndIf
- Return Self
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed list box.
-EndRem
-Type TMListBox Extends TMListWidget
- Rem
- bbdoc: Creates a managed list box.
- returns: The created list box.
- about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateListBox(), except that @group is a TMWidget.
- If @values is not NULL it is used to load up the initial options.
- EndRem
- Method Create:TMListBox(x:Int,y:Int, w:Int, h:Int, group:TMWidget, values:TMListEntry[]=Null)
- OnIndexChangedEvent=New TMWEventListInt
- BaseInitialise(CreateListBox(x,y,w,h,group.gadget),group)
- typename="TMListBox"
- If values
- AddItems(values)
- EndIf
- Return Self
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed tabber.
-EndRem
-Type TMTabber Extends TMListWidget
- Field pages:TMWidget[][]
-
- Rem
- bbdoc: Creates a managed tabber.
- returns: The created tabber.
- about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateTabber(), except that @group is a TMWidget.
- If @values is not NULL it is used to load up the initial options.
- EndRem
- Method Create:TMTabber(x:Int,y:Int, w:Int, h:Int, group:TMWidget, values:TMListEntry[]=Null)
- OnIndexChangedEvent=New TMWEventListInt
- BaseInitialise(CreateTabber(x,y,w,h,group.gadget),group)
- typename="TMTabber"
- If values
- AddItems(values)
- EndIf
- Return Self
- End Method
-
- Rem
- bbdoc: Defines the gadgets to appear on each page of the tabber.
- about: @widgets is an array of @TMWidget arrays. Each sub-array is one page.
- EndRem
- Method SetPages(widgets:TMWidget[][])
- pages=widgets
- End Method
-
- Rem
- bbdoc: Set the currently selected page.
- about: This will hide/show the widgets defined by @DefinePages() as appropriate.
- EndRem
- Method SetSelectedIndex(index:Int)
- SelectGadgetItem(gadget,index)
-
- If pages
- For Local f:Int=0 Until pages.length
- For Local w:TMWidget=EachIn pages[f]
- w.Hidden(f<>index)
- Next
- Next
- EndIf
- End Method
-
- Rem
- bbdoc: This default implementation will switch the widgets as defined by @DefinePages()
- EndRem
- Method OnIndexChanged(index:Int)
- If index>-1 And pages
- For Local f:Int=0 Until pages.length
- For Local w:TMWidget=EachIn pages[f]
- w.Hidden(f<>index)
- Next
- Next
- EndIf
- End Method
-
-End Type
-
-
-Rem
-bbdoc: Defines a managed HTML View.
-EndRem
-Type TMHTMLView Extends TMWidget
- Rem
- bbdoc: Creates a managed HTML View.
- returns: The created HTML View.
- about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateHMTLView(), except that @group is a TMWidget.
- EndRem
- Method Create:TMHTMLView(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- OnPageLoadedEvent=New TMWEventListString
- OnSelectURLEvent=New TMWEventListString
- BaseInitialise(CreateHTMLView(x,y,w,h,group.gadget,style),group)
- typename="TMHTMLView"
- Return Self
- End Method
-
- Rem
- bbdoc: The current URL.
- EndRem
- Method CurrentURL:String()
- Return HtmlViewCurrentURL(gadget)
- End Method
-
- Rem
- bbdoc: Enter the URL to goto.
- EndRem
- Method Go(url:String)
- HtmlViewGo(gadget,url)
- End Method
-
- Rem
- bbdoc: Go back in the history.
- EndRem
- Method Back()
- HtmlViewBack(gadget)
- End Method
-
- Rem
- bbdoc: Go forward in the history.
- EndRem
- Method Forward()
- HtmlViewForward(gadget)
- End Method
-
- Rem
- bbdoc:Run a script.
- EndRem
- Method RunScript:String(script:String)
- HtmlViewRun(gadget,script)
- End Method
-
- Rem
- bbdoc: If HTMLVIEW_NONAVIGATE is set in the styles, then this is called when a link is clicked.
- about: @url is the selected URL.
- EndRem
- Method OnSelectURL(url:String)
- End Method
-
- Rem
- bbdoc: If HTMLVIEW_NONAVIGATE is set in the styles, then this is called when a link is clicked.
- EndRem
- Field OnSelectURLEvent:TMWEventListString
-
- Rem
- bbdoc: Called when the page finishes loading.
- about: @url is the loaded URL.
- EndRem
- Method OnPageLoaded(url:String)
- End Method
-
- Rem
- bbdoc: Called when the page finishes loading.
- EndRem
- Field OnPageLoadedEvent:TMWEventListString
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnSelectURL(e.extra.ToString())
- OnSelectURLEvent.Fire(Self,e.extra.ToString())
- Case EVENT_GADGETDONE
- OnPageLoaded(CurrentURL())
- OnPageLoadedEvent.Fire(Self,CurrentURL())
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Type TMTreeNode
- Field path:String
- Field node:TGadget
- Field tag:Object
- Field icon:Int
- Function Create:TMTreeNode(path:String, node:TGadget, tag:Object, icon:Int)
- Local o:TMTreeNode=New TMTreeNode
- o.path=path
- o.node=node
- o.tag=tag
- o.icon=icon
- Return o
- End Function
-End Type
-
-Rem
-bbdoc: Defines a managed tree view.
-about: The tree view works by treating its entries as if in a simple file system.
-EndRem
-Type TMTreeView Extends TMWidget
- Field map:TMap
- Field gmap:TMap
- Field update:Int
-
- Rem
- bbdoc: Creates a managed tree view.
- returns: The created tree view.
- about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateTreeView(), except that @group is a TMWidget.
- EndRem
- Method Create:TMTreeView(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- update=False
- map=New TMap
- gmap=New TMap
- OnSelectedEvent=New TMWEventListStringObject
- OnClickedEvent=New TMWEventListStringObject
- OnMenuEvent=New TMWEventListStringObject
- OnExpandedEvent=New TMWEventListStringObject
- OnCollapsedEvent=New TMWEventListStringObject
- BaseInitialise(CreateTreeView(x,y,w,h,group.gadget,style),group)
- typename="TMNodeView"
- map.Insert("/",TMTreeNode.Create("/",TreeViewRoot(gadget),"/",-1))
- Return Self
- End Method
-
- Method ResolvePath:TMTreeNode(path:String)
- Return TMTreeNode(map.ValueForKey(path))
- End Method
-
- Method ResolveGadget:TMTreeNode(g:TGadget)
- Return ResolvePath(gmap.ValueForKey(g).ToString())
- End Method
-
- Method Prune(path:String)
- Local l:TList=CreateList()
-
- ' Not sure if this is overly ineffecient -- just being safe as in most languages deleting whilst iterating
- ' is not recommended...
- '
- For Local k:String=EachIn map.Keys()
- If k=path Or k.Find(path+"/")=0
- l.AddLast(k)
- EndIf
- Next
-
- For Local k:String=EachIn l
- Local n:TMTreeNode=ResolvePath(k)
- map.Remove(k)
- gmap.Remove(n.node)
- Next
- End Method
-
- Rem
- bbdoc: Set an icon strip.
- EndRem
- Method SetIconStrip(icons:TIconStrip)
- SetGadgetIconStrip(gadget,icons)
- End Method
-
- Rem
- bbdoc: The number of nodes in the view that are direct children on the passed node.
- returns: The number of nodes.
- about: @path is the path to count from. Unfortunately counting from the root (/) doesn't work, so it returns -1.
- EndRem
- Method CountChildren:Int(path:String)
- If path="/"
- Return -1
- EndIf
-
- Local node:TMTreeNode=ResolvePath(path)
-
- If node
- Return CountTreeViewNodes(node.node)
- Else
- Return 0
- EndIf
- End Method
-
- Rem
- bbdoc: Remove nodes from the tree.
- about: Attempting to remove the root node (/) will fail.
- EndRem
- Method Remove(path:String)
- If path<>"/"
- Local node:TMTreeNode=ResolvePath(path)
-
- If node
- FreeTreeViewNode(node.node)
- Prune(path)
- EndIf
- EndIf
- End Method
-
- Rem
- bbdoc: Don't redraw gadget when adding nodes.
- EndRem
- Method BeginUpdate()
- update=True
- End Method
-
-
- Rem
- bbdoc: Allow redraw of gadget when adding nodes.
- EndRem
- Method EndUpdate()
- update=False
- End Method
-
-
- Rem
- bbdoc: Add/modify nodes in the tree.
- about: @path is the path to the node. This silently fails if the parent nodes don't exist. @tag is an Object that the entry is tagged with.
- ToString() is called on this to create the text for the entry (so passing a String works fine).
- @icon is the icon to use. Note that if you set an icon strip, then this seems to use the first icon (on Win32 at least) if set to -1.
- EndRem
- Method Set(path:String, tag:Object, icon:Int=-1)
- Local parent:TMTreeNode=ResolvePath(FixedExtractDir(path))
-
- If parent
- Local node:TMTreeNode=ResolvePath(path)
-
- If node
- ModifyTreeViewNode(node.node,tag.ToString(),icon)
- Else
- node=TMTreeNode.Create(path,AddTreeViewNode(tag.ToString(),parent.node,icon),tag,icon)
- map.Insert(path,node)
- gmap.Insert(node.node,path)
- EndIf
-
- node.tag=tag
- node.icon=icon
-
- If Not update
- RedrawGadget(gadget)
- EndIf
- EndIf
- End Method
-
- Rem
- bbdoc: Get the tag at a node.
- returns: The tag, or NULL for unknown node.
- EndRem
- Method GetNodeTag:Object(path:String)
- Local node:TMTreeNode=ResolvePath(path)
- If node
- Return node.tag
- Else
- Return Null
- EndIf
- End Method
-
- Rem
- bbdoc: Get the icon at a node.
- returns: The icon, or -1 for none or unknown node.
- EndRem
- Method GetNodeIcon:Int(path:String)
- Local node:TMTreeNode=ResolvePath(path)
- If node
- Return node.icon
- Else
- Return -1
- EndIf
- End Method
-
- Rem
- bbdoc: Expand a node on the tree.
- EndRem
- Method ExpandNode(path:String)
- Local node:TMTreeNode=ResolvePath(path)
-
- If node
- ExpandTreeViewNode(node.node)
- EndIf
- End Method
-
- Rem
- bbdoc: Collapse a node on the tree.
- EndRem
- Method CollapseNode(path:String)
- Local node:TMTreeNode=ResolvePath(path)
-
- If node
- CollapseTreeViewNode(node.node)
- EndIf
- End Method
-
- Rem
- bbdoc: Called when the an item is selected.
- about: @path is the path to the selected item, @tag is the tag for that item.
- EndRem
- Method OnSelected(path:String, tag:Object)
- End Method
-
- Rem
- bbdoc: Called when the an item is selected.
- EndRem
- Field OnSelectedEvent:TMWEventListStringObject
-
- Rem
- bbdoc: Called when the an item is double clicked.
- about: @path is the path to the selected item, @tag is the tag for that item.
- EndRem
- Method OnClicked(path:String, tag:Object)
- End Method
-
- Rem
- bbdoc: Called when the an item is double clicked.
- EndRem
- Field OnClickedEvent:TMWEventListStringObject
-
- Rem
- bbdoc: Called when the a context menu is requested.
- about: @path is the path to the selected item, @tag is the tag for that item.
- EndRem
- Method OnMenu(path:String, tag:Object)
- End Method
-
- Rem
- bbdoc: Called when the an item is selected.
- EndRem
- Field OnMenuEvent:TMWEventListStringObject
-
- Rem
- bbdoc: Called when a node is expanded.
- about: @path is the path to the selected item, @tag is the tag for that item.
- EndRem
- Method OnExpanded(path:String, tag:Object)
- End Method
-
- Rem
- bbdoc: Called when a node is expanded.
- EndRem
- Field OnExpandedEvent:TMWEventListStringObject
-
- Rem
- bbdoc: Called when a node is collapsed.
- about: @path is the path to the selected item, @tag is the tag for that item.
- EndRem
- Method OnCollapsed(path:String, tag:Object)
- End Method
-
- Rem
- bbdoc: Called when a node is collapsed.
- EndRem
- Field OnCollapsedEvent:TMWEventListStringObject
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETSELECT
- Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
- If n
- OnSelected(n.path,n.tag)
- OnSelectedEvent.Fire(Self,n.path,n.tag)
- EndIf
- Case EVENT_GADGETACTION
- Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
- If n
- OnClicked(n.path,n.tag)
- OnClickedEvent.Fire(Self,n.path,n.tag)
- EndIf
- Case EVENT_GADGETOPEN
- Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
- If n
- OnExpanded(n.path,n.tag)
- OnExpandedEvent.Fire(Self,n.path,n.tag)
- EndIf
- Case EVENT_GADGETCLOSE
- Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
- If n
- OnCollapsed(n.path,n.tag)
- OnCollapsedEvent.Fire(Self,n.path,n.tag)
- EndIf
- Case EVENT_GADGETMENU
- Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
- If n
- OnMenu(n.path,n.tag)
- OnMenuEvent.Fire(Self,n.path,n.tag)
- EndIf
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Type TMenuItem
- Field id:Int
- Field owner:TMMenu
- Field path:String
- Field tag:Object
- Field gadget:TGadget
- Field callback(menu:TMMenu, path:String, tag:Object)
- Function Create:TMenuItem(owner:TMMenu, id:Int, path:String, gadget:TGadget, tag:Object, callback(menu:TMMenu, path:String, tag:Object))
- Local o:TMenuItem=New TMenuItem
- o.owner=owner
- o.id=id
- o.path=path
- o.gadget=gadget
- o.tag=tag
- o.callback=callback
- Return o
- End Function
-End Type
-
-
-Rem
-bbdoc: Defines a managed menu.
-about: Note that TMMenu is <b>NOT</b> a TMWidget.
-EndRem
-Type TMMenu
-
- Field root:TGadget
- Field map:TMap
- Field win:TMWindow
-
- Rem
- bbdoc: Creates a managed menu that is associated as a window menu.
- returns: The created menu.
- about: @window is the window the menu is attached to.
- EndRem
- Method CreateWindowMenu:TMMenu(window:TMWindow)
- map=New TMap
- root=WindowMenu(window.gadget)
- win=window
- SetRoot()
- Return Self
- End Method
-
- Rem
- bbdoc: Creates a managed menu that can be used as a popup menu.
- returns: The created menu.
- EndRem
- Method CreatePopupMenu:TMMenu()
- map=New TMap
- root=CreateMenu("",0,Null)
- win=Null
- SetRoot()
- Return Self
- End Method
-
- Method Delete()
- Clear()
- If Not win
- FreeMenu(root)
- EndIf
- End Method
-
- Rem
- bbdoc: Clear all items from the menu
- EndRem
- Method Clear()
- For Local m:TMenuItem=EachIn TMapEnumerator(MapValues(map))
- FreeMenu(m.gadget)
- Static.DeregisterMenuItem(m)
- Next
- map.Clear()
- SetRoot()
- End Method
-
- Method SetRoot()
- map.Insert("/",TMenuItem.Create(Self,0,"/",root,Null,Null))
- End Method
-
- Method ResolvePath:TMenuItem(path:String)
- Return TMenuItem(map.ValueForKey(path))
- End Method
-
- Method Prune(path:String)
- Local l:TList=CreateList()
-
- ' Not sure if this is overly ineffecient -- just being safe as in most languages deleting whilst iterating
- ' is not recommended...
- '
- For Local k:String=EachIn map.Keys()
- If k=path Or k.Find(path+"/")=0
- l.AddLast(k)
- EndIf
- Next
-
- For Local k:String=EachIn l
- Local n:TMenuItem=ResolvePath(k)
- map.Remove(k)
- Static.DeregisterMenuItem(n)
- FreeMenu(n.gadget)
- Next
- End Method
-
- Rem
- bbdoc: Add a menu option.
- about: @path is the path to the menu item. This silently fails if the parent menus don't exist. @tag is an Object that the entry is tagged with.
- ToString() is called on this to create the text for the menu (so passing a String works fine). If @callback is not null, then it is called when
- this option is selected.
- @hotkey and @modifier are as in MaxGUI's CreateMenu().
- EndRem
- Method Set(path:String, tag:Object, callback(menu:TMMenu, path:String, tag:Object)=Null, hotkey:Int=0, modifier:Int=0)
- If path<>"/"
- Local parent:TMenuItem=ResolvePath(FixedExtractDir(path))
-
- If parent
- Local node:TMenuItem=ResolvePath(path)
-
- If node
- SetMenuText(node.gadget,tag.ToString())
- Else
- Local id:Int=Static.NextMenuID()
- node=TMenuItem.Create(Self,id,path,CreateMenu(tag.ToString(),id,parent.gadget,hotkey,modifier),tag,callback)
- map.Insert(path,node)
- Static.RegisterMenuItem(node)
- EndIf
-
- node.tag=tag
-
- If win
- UpdateWindowMenu(win.gadget)
- EndIf
- EndIf
- EndIf
- End Method
-
- Rem
- bbdoc: Remove menu item and its children.
- about: @path is the path to the menu item. Root cannot be removed.
- EndRem
- Method Remove(path:String)
- If path<>"/"
- Prune(path)
-
- If win
- UpdateWindowMenu(win.gadget)
- EndIf
- EndIf
- End Method
-
- Rem
- bbdoc: Change a menu tag (and therefore its text).
- about: @path is the path to the menu item. Root cannot be changed.
- EndRem
- Method SetTag(path:String, tag:Object)
- If path<>"/"
- Local node:TMenuItem=ResolvePath(path)
-
- If node
- SetMenuText(node.gadget,tag.ToString())
- node.tag=tag
-
- If win
- UpdateWindowMenu(win.gadget)
- EndIf
- EndIf
- EndIf
- End Method
-
- Rem
- bbdoc: Change a menu check.
- about: @path is the path to the menu item. Root cannot be changed.
- EndRem
- Method Check(path:String, check:Int)
- If path<>"/"
- Local node:TMenuItem=ResolvePath(path)
-
- If node
- If check
- CheckMenu(node.gadget)
- Else
- UncheckMenu(node.gadget)
- EndIf
-
- If win
- UpdateWindowMenu(win.gadget)
- EndIf
- EndIf
- EndIf
- End Method
-
- Rem
- about: Is a menu item checked.
- EndRem
- Method IsChecked:Int(path:String)
- Local ret:Int=False
-
- If path<>"/"
- Local node:TMenuItem=ResolvePath(path)
-
- If node
- ret=MenuChecked(node.gadget)
- EndIf
- EndIf
-
- Return ret
- End Method
-
- Rem
- bbdoc: Enable/disable a menu item.
- about: @path is the path to the menu item. Root cannot be changed.
- EndRem
- Method Enable(path:String, enab:Int)
- If path<>"/"
- Local node:TMenuItem=ResolvePath(path)
-
- If node
- If enab
- EnableMenu(node.gadget)
- Else
- DisableMenu(node.gadget)
- EndIf
-
- If win
- UpdateWindowMenu(win.gadget)
- EndIf
- EndIf
- EndIf
- End Method
-
- Rem
- about: Is a menu item enabled.
- EndRem
- Method IsEnabled:Int(path:String)
- Local ret:Int=False
-
- If path<>"/"
- Local node:TMenuItem=ResolvePath(path)
-
- If node
- ret=MenuEnabled(node.gadget)
- EndIf
- EndIf
-
- Return ret
- End Method
-
- Rem
- bbdoc: Called when the an item is selected in the menu.
- EndRem
- Method OnMenuItem(path:String, tag:Object)
- End Method
-
- Rem
- bbdoc: Popup the menu.
- about: @win is a gadget to pass to MaxGUI. For some reason you need this, and the docs say it should be a window.
- When I've tried any gadget would suffice, but don't come crying to me if it stops working for non-window gadgets.
- EndRem
- Method Popup(g:TMWidget)
- PopupWindowMenu(g.gadget,root)
- End Method
-
- Method ToString:String()
- Return "TMMenu:"+Super.ToString()
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed canvas.
-EndRem
-Type TMCanvas Extends TMWidget
-
- Rem
- bbdoc: Creates a managed canvas.
- returns: The created canvas.
- about: @x, @y, @w, @h, @group, @style and @gfxflags act the same as the MaxGUI arguments to @CreateCanvas(), except that @group is a TMWidget.
- EndRem
- Method Create:TMCanvas(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- OnRedrawEvent=New TMWEventListVoid
- OnButtonDownEvent=New TMWEventListInt
- OnButtonUpEvent=New TMWEventListInt
- OnMouseMoveEvent=New TMWEventListIntInt
- OnMouseWheelEvent=New TMWEventListInt
- OnKeyDownEvent=New TMWEventListInt
- OnKeyUpEvent=New TMWEventListInt
- OnKeyEvent=New TMWEventListInt
- BaseInitialise(CreateCanvas(x,y,w,h,group.gadget,style),group)
- typename="TMCanvas"
- Return Self
- End Method
-
- Rem
- bbdoc: Set the graphics so that the canvas can be drawn onto.
- EndRem
- Method SetupGraphics()
- SetGraphics(CanvasGraphics(gadget))
- End Method
-
- Rem
- bbdoc: Called when the canvas should be redrawn.
- EndRem
- Method OnRedraw()
- End Method
-
- Rem
- bbdoc: Called when the canvas should be redrawn.
- EndRem
- Field OnRedrawEvent:TMWEventListVoid
-
- Rem
- bbdoc: Called when the a mouse button is pressed.
- about: @button is the pressed button.
- EndRem
- Method OnButtonDown(button:Int)
- End Method
-
- Rem
- bbdoc: Called when the a mouse button is pressed.
- EndRem
- Field OnButtonDownEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when the a mouse button is released.
- about: @button is the released button.
- EndRem
- Method OnButtonUp(button:Int)
- End Method
-
- Rem
- bbdoc: Called when the a mouse button is released.
- EndRem
- Field OnButtonUpEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when the mouse moves.
- about: @x and @y are the mouse co-ordinates.
- EndRem
- Method OnMouseMove(x:Int, y:Int)
- End Method
-
- Rem
- bbdoc: Called when the an item is selected.
- EndRem
- Field OnMouseMoveEvent:TMWEventListIntInt
-
- Rem
- bbdoc: Called when the mouse wheel moves.
- about: @delta is the amount the wheel moves.
- EndRem
- Method OnMouseWheel(delta:Int)
- End Method
-
- Rem
- bbdoc: Called when the mouse wheel moves.
- EndRem
- Field OnMouseWheelEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when a key is held down.
- about: @code is the key code.
- EndRem
- Method OnKeyDown(code:Int)
- End Method
-
- Rem
- bbdoc: Called when a key is held down.
- EndRem
- Field OnKeyDownEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when a key is released.
- about: @code is the key code.
- EndRem
- Method OnKeyUp(code:Int)
- End Method
-
- Rem
- bbdoc: Called when a key is released.
- EndRem
- Field OnKeyUpEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when a key character is generated.
- about: @code is the unicode value.
- EndRem
- Method OnKey(code:Int)
- End Method
-
- Rem
- bbdoc: Called when a key character is generated.
- EndRem
- Field OnKeyEvent:TMWEventListInt
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETPAINT
- OnRedraw()
- OnRedrawEvent.Fire(Self)
- Case EVENT_MOUSEDOWN
- OnButtonDown(e.data)
- OnButtonDownEvent.Fire(Self,e.data)
- Case EVENT_MOUSEUP
- OnButtonUp(e.data)
- OnButtonUpEvent.Fire(Self,e.data)
- Case EVENT_MOUSEMOVE
- OnMouseMove(e.x,e.y)
- OnMouseMoveEvent.Fire(Self,e.x,e.y)
- Case EVENT_MOUSEWHEEL
- OnMouseWheel(e.data)
- OnMouseWheelEvent.Fire(Self,e.data)
- Case EVENT_KEYDOWN
- OnKeyDown(e.data)
- OnKeyDownEvent.Fire(Self,e.data)
- Case EVENT_KEYUP
- OnKeyUp(e.data)
- OnKeyUpEvent.Fire(Self,e.data)
- Case EVENT_KEYCHAR
- OnKey(e.data)
- OnKeyEvent.Fire(Self,e.data)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a toolbar.
-EndRem
-Type TMToolbar Extends TMWidget
- Rem
- bbdoc: Creates a managed toolbar.
- returns: The created toolbar.
- about: @source, @group and @style act the same as the MaxGUI arguments to @CreateToolBar(), except that @group is a TMWidget.
- If @values is not NULL it is used to load up the initial options.
- <b>IMPORTANT</b>: It is really not recommended to use COMBOBOX_EDITABLE as OnIndexChanged() is called when the user edits the field.
- There seems to be no easy way to remedy this.
- EndRem
- Method Create:TMToolbar(source:Object, group:TMWidget, style:Int=0)
- OnSelectedEvent=New TMWEventListInt
- BaseInitialise(CreateToolBar(source,0,0,0,0,group.gadget,style),group)
- typename="TMToolbar"
- Return Self
- End Method
-
- Rem
- bbdoc: Adds an item to the toolbar.
- EndRem
- Method AddItem(icon:Int, flags:Int=0, tooltip:String=Null)
- AddGadgetItem(gadget,"",flags,icon,tooltip,Null)
- End Method
-
- Rem
- bbdoc: Set the tooltips.
- EndRem
- Method SetTooltips(tips:String[])
- SetToolBarTips(gadget,tips)
- End Method
-
- Rem
- bbdoc: Enable or disable a particular item.
- EndRem
- Method ItemEnabled(index:Int, state:Int)
- If state
- EnableGadgetItem(gadget,index)
- Else
- DisableGadgetItem(gadget,index)
- EndIf
- End Method
-
- Rem
- bbdoc: Called when an icon is selected.
- about: @index is the selected index.
- EndRem
- Method OnSelected(index:Int)
- End Method
-
- Rem
- bbdoc: Called when an icon is selected.
- EndRem
- Field OnSelectedEvent:TMWEventListInt
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_GADGETACTION
- OnSelected(e.data)
- OnSelectedEvent.Fire(Self,e.data)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed panel.
-EndRem
-Type TMPanel Extends TMWidget
-
- Rem
- bbdoc: Creates a managed panel.
- returns: The created panel.
- about: @x, @y, @w, @h, @group, @style and @title act the same as the MaxGUI arguments to @CreatePanel(), except that @group is a TMWidget.
- EndRem
- Method Create:TMPanel(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0, title:String="")
- OnButtonDownEvent=New TMWEventListInt
- OnButtonUpEvent=New TMWEventListInt
- OnMouseMoveEvent=New TMWEventListIntInt
- OnMouseWheelEvent=New TMWEventListInt
- OnKeyDownEvent=New TMWEventListInt
- OnKeyUpEvent=New TMWEventListInt
- OnKeyEvent=New TMWEventListInt
- BaseInitialise(CreatePanel(x,y,w,h,group.gadget,style,title),group)
- typename="TMPanel"
- Return Self
- End Method
-
- Rem
- bbdoc: Called when the a mouse button is pressed.
- about: @button is the pressed button.
- EndRem
- Method OnButtonDown(button:Int)
- End Method
-
- Rem
- bbdoc: Called when the a mouse button is pressed.
- EndRem
- Field OnButtonDownEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when the a mouse button is released.
- about: @button is the released button.
- EndRem
- Method OnButtonUp(button:Int)
- End Method
-
- Rem
- bbdoc: Called when the a mouse button is released.
- EndRem
- Field OnButtonUpEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when the mouse moves.
- about: @x and @y are the mouse co-ordinates.
- EndRem
- Method OnMouseMove(x:Int, y:Int)
- End Method
-
- Rem
- bbdoc: Called when the an item is selected.
- EndRem
- Field OnMouseMoveEvent:TMWEventListIntInt
-
- Rem
- bbdoc: Called when the mouse wheel moves.
- about: @delta is the amount the wheel moves.
- EndRem
- Method OnMouseWheel(delta:Int)
- End Method
-
- Rem
- bbdoc: Called when the mouse wheel moves.
- EndRem
- Field OnMouseWheelEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when a key is held down.
- about: @code is the key code.
- EndRem
- Method OnKeyDown(code:Int)
- End Method
-
- Rem
- bbdoc: Called when a key is held down.
- EndRem
- Field OnKeyDownEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when a key is released.
- about: @code is the key code.
- EndRem
- Method OnKeyUp(code:Int)
- End Method
-
- Rem
- bbdoc: Called when a key is released.
- EndRem
- Field OnKeyUpEvent:TMWEventListInt
-
- Rem
- bbdoc: Called when a key character is generated.
- about: @code is the unicode value.
- EndRem
- Method OnKey(code:Int)
- End Method
-
- Rem
- bbdoc: Called when a key character is generated.
- EndRem
- Field OnKeyEvent:TMWEventListInt
-
- Method Handle(e:TEvent)
- Select e.id
- Case EVENT_MOUSEDOWN
- OnButtonDown(e.data)
- OnButtonDownEvent.Fire(Self,e.data)
- Case EVENT_MOUSEUP
- OnButtonUp(e.data)
- OnButtonUpEvent.Fire(Self,e.data)
- Case EVENT_MOUSEMOVE
- OnMouseMove(e.x,e.y)
- OnMouseMoveEvent.Fire(Self,e.x,e.y)
- Case EVENT_MOUSEWHEEL
- OnMouseWheel(e.data)
- OnMouseWheelEvent.Fire(Self,e.data)
- Case EVENT_KEYDOWN
- OnKeyDown(e.data)
- OnKeyDownEvent.Fire(Self,e.data)
- Case EVENT_KEYUP
- OnKeyUp(e.data)
- OnKeyUpEvent.Fire(Self,e.data)
- Case EVENT_KEYCHAR
- OnKey(e.data)
- OnKeyEvent.Fire(Self,e.data)
- Default
- Super.Handle(e)
- End Select
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a managed progress bar.
-EndRem
-Type TMProgressBar Extends TMWidget
-
- Rem
- bbdoc: Creates a managed progress bar.
- returns: The created progress bar.
- about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateProgBar(), except that @group is a TMWidget.
- EndRem
- Method Create:TMProgressBar(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
- BaseInitialise(CreateProgBar(x,y,w,h,group.gadget,style),group)
- typename="TMProgressBar"
- Return Self
- End Method
-
- Rem
- bbdoc: Set the value for the progress bar.
- about: @value is the value (between 0 and 1).
- EndRem
- Method SetValue(value:Double)
- UpdateProgBar(gadget,value)
- End Method
-End Type
-
-
-Rem
-bbdoc: Enters the event processing loop.
-about: @top is the top level TMWindow For the application. The loop continues Until the @closed Field of this window is TRUE.
-Your code can do it's own event loop if required -- all this function does is continually call WaitEvent and is simply provided as
-a basic main loop.
-EndRem
-Function MWidgetMainLoop(top:TMWindow)
- While Not top.closed
- WaitEvent()
- Wend
-End Function
-
-
-Private
-
-Function FixedExtractDir:String(p:String)
- p=ExtractDir(p)
- If p.length=0
- p="/"
- EndIf
- Return p
-End Function
-
-Type Static
- Global list:TList
- Global menu:TList
- Global menuid:Int
-
- Function Init()
- list=CreateList()
- menu=CreateList()
- menuid=0
- AddHook(EmitEventHook,EventHandler)
- End Function
-
- Function EventHandler:Object(id:Int, data:Object, context:Object)
- Local e:TEvent=TEvent(data)
-
- DebugLog "Got event : " + e.ToString()
-
- If e
- If e.id=EVENT_MENUACTION
- For Local m:TMenuItem=EachIn menu
- If m.id=e.data
- DebugLog "Passing menu event to " + m.owner.ToString()
- m.owner.OnMenuItem(m.path,m.tag)
- If m.callback
- m.callback(m.owner,m.path,m.tag)
- EndIf
- EndIf
- Next
- Else
- For Local g:TMWidget=EachIn list
- If g And g.gadget And g.gadget=e.source
- DebugLog "Passing event to " + g.ToString()
- g.Handle(e)
- EndIf
- Next
- EndIf
- EndIf
-
- Return e
- End Function
-
- Function Register(w:TMWidget)
- list.AddLast(w)
- w.OnManage()
- w.OnManageEvent.Fire(w)
- End Function
-
- Function Deregister(w:TMWidget)
- w.OnUnmanage()
- w.OnUnmanageEvent.Fire(w)
- list.Remove(w)
- End Function
-
- Function RegisterMenuItem(m:TMenuItem)
- menu.AddLast(m)
- End Function
-
- Function DeregisterMenuItem(m:TMenuItem)
- menu.Remove(m)
- End Function
-
- Function NextMenuID:Int()
- menuid:+1
- Return menuid
- End Function
-End Type
-
-Static.Init()
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.mwidget
+about: <p>Provides a simply class based interface to the MaxGUI. Note that all widgets have create type methods. For these to work correctly with
+sub-classes they must be called through a new operation, e.g.</p>
+<pre>
+Type MyApp Extends TMWindow
+&nbsp;&nbsp;&nbsp;&nbsp;Method OnClose(e:TEvent)
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closed=Confirm("Really quit?")
+&nbsp;&nbsp;&nbsp;&nbsp;End Method
+End Type
+
+Local window:TMWindow=New MyApp.Create("Test",100,100,640,400)
+MWidgetMainLoop(window)
+</pre>
+<p>
+There are two methods of getting events. One is to subclass and override the events, as with the @OnClose() above. The other is to set
+function pointers in the matching event lists, @OnCloseEvent in this instance. For instance:
+</p>
+<pre>
+Function OnClose(o:TMWidget)
+&nbsp;&nbsp;&nbsp;&nbsp;Local w:TMWindow=TMWindow(o)
+&nbsp;&nbsp;&nbsp;&nbsp;w.closed=Confirm("Really quit?")
+End Function
+
+Local window:TMWindow=New TMWindow.Create("Test",100,100,640,400)
+window.OnCloseEvent.Add(OnClose)
+MWidgetMainLoop(window)
+</pre>
+<p>
+When using the function callback method of capturing events, the parameters to the function are the same as the overridable method with the addition
+of the managed widget which is passed in as the first argument.
+</p>
+EndRem
+Module noddybox.mwidget
+
+ModuleInfo "Framework: Simple Managed Widget Classes"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import maxgui.maxgui
+Import brl.linkedlist
+Import brl.event
+Import brl.timer
+Import brl.map
+Import brl.filesystem
+Import brl.eventqueue
+
+Type TMWEventListBase Abstract
+ Field list:TList
+ Method New()
+ list=CreateList()
+ End Method
+End Type
+
+Type TMWFuncVoid
+ Field func(w:TMWidget)
+ Function Create:TMWFuncVoid(func(w:TMWidget))
+ Local o:TMWFuncVoid=New TMWFuncVoid
+ o.func=func
+ Return o
+ End Function
+End Type
+
+Type TMWFuncInt
+ Field func(w:TMWidget, a:Int)
+ Function Create:TMWFuncInt(func(w:TMWidget, a:Int))
+ Local o:TMWFuncInt=New TMWFuncInt
+ o.func=func
+ Return o
+ End Function
+End Type
+
+Type TMWFuncIntInt
+ Field func(w:TMWidget, a:Int, b:Int)
+ Function Create:TMWFuncIntInt(func(w:TMWidget, a:Int, b:Int))
+ Local o:TMWFuncIntInt=New TMWFuncIntInt
+ o.func=func
+ Return o
+ End Function
+End Type
+
+Type TMWFuncString
+ Field func(w:TMWidget, a:String)
+ Function Create:TMWFuncString(func(w:TMWidget, a:String))
+ Local o:TMWFuncString=New TMWFuncString
+ o.func=func
+ Return o
+ End Function
+End Type
+
+
+Type TMWFuncStringObject
+ Field func(w:TMWidget, a:String, b:Object)
+ Function Create:TMWFuncStringObject(func(w:TMWidget, a:String, b:Object))
+ Local o:TMWFuncStringObject=New TMWFuncStringObject
+ o.func=func
+ Return o
+ End Function
+End Type
+
+
+Rem
+bbdoc: Defines an event list for functions that take the parameters (w:TMWidget)
+EndRem
+Type TMWEventListVoid Extends TMWEventListBase Final
+ Rem
+ bbdoc: Adds a callback function.
+ EndRem
+ Method Add(func(w:TMWidget))
+ list.AddLast(TMWFuncVoid.Create(func))
+ End Method
+
+ Rem
+ bbdoc: Clears all callback functions.
+ EndRem
+ Method Clear()
+ list.Clear()
+ End Method
+
+ Rem
+ bbdoc: Removes a callback function.
+ EndRem
+ Method Remove(func(w:TMWidget))
+ For Local fp:TMWFuncVoid=EachIn list
+ If fp.func=func
+ list.Remove(fp)
+ Return
+ EndIf
+ Next
+ End Method
+
+ Method Fire(w:TMWidget)
+ For Local fp:TMWFuncVoid=EachIn list
+ fp.func(w)
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:Int)
+EndRem
+Type TMWEventListInt Extends TMWEventListBase Final
+ Rem
+ bbdoc: Adds a callback function.
+ EndRem
+ Method Add(func(w:TMWidget, a:Int))
+ list.AddLast(TMWFuncInt.Create(func))
+ End Method
+
+ Rem
+ bbdoc: Clears all callback functions.
+ EndRem
+ Method Clear()
+ list.Clear()
+ End Method
+
+ Rem
+ bbdoc: Removes a callback function.
+ EndRem
+ Method Remove(func(w:TMWidget, a:Int))
+ For Local fp:TMWFuncInt=EachIn list
+ If fp.func=func
+ list.Remove(fp)
+ Return
+ EndIf
+ Next
+ End Method
+
+ Method Fire(w:TMWidget, a:Int)
+ For Local fp:TMWFuncInt=EachIn list
+ fp.func(w,a)
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:String)
+EndRem
+Type TMWEventListString Extends TMWEventListBase Final
+ Rem
+ bbdoc: Adds a callback function.
+ EndRem
+ Method Add(func(w:TMWidget, a:String))
+ list.AddLast(TMWFuncString.Create(func))
+ End Method
+
+ Rem
+ bbdoc: Clears all callback functions.
+ EndRem
+ Method Clear()
+ list.Clear()
+ End Method
+
+ Rem
+ bbdoc: Removes a callback function.
+ EndRem
+ Method Remove(func(w:TMWidget, a:String))
+ For Local fp:TMWFuncString=EachIn list
+ If fp.func=func
+ list.Remove(fp)
+ Return
+ EndIf
+ Next
+ End Method
+
+ Method Fire(w:TMWidget, a:String)
+ For Local fp:TMWFuncString=EachIn list
+ fp.func(w,a)
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:Int, b:Int)
+EndRem
+Type TMWEventListIntInt Extends TMWEventListBase Final
+ Rem
+ bbdoc: Adds a callback function.
+ EndRem
+ Method Add(func(w:TMWidget, a:Int, b:Int))
+ list.AddLast(TMWFuncIntInt.Create(func))
+ End Method
+
+ Rem
+ bbdoc: Clears all callback functions.
+ EndRem
+ Method Clear()
+ list.Clear()
+ End Method
+
+ Rem
+ bbdoc: Removes a callback function.
+ EndRem
+ Method Remove(func(w:TMWidget, a:Int, b:Int))
+ For Local fp:TMWFuncIntInt=EachIn list
+ If fp.func=func
+ list.Remove(fp)
+ Return
+ EndIf
+ Next
+ End Method
+
+ Method Fire(w:TMWidget, a:Int, b:Int)
+ For Local fp:TMWFuncIntInt=EachIn list
+ fp.func(w,a,b)
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines an event list for functions that take the parameters (w:TMWidget, a:String, b:Object)
+EndRem
+Type TMWEventListStringObject Extends TMWEventListBase Final
+ Rem
+ bbdoc: Adds a callback function.
+ EndRem
+ Method Add(func(w:TMWidget, a:String, b:Object))
+ list.AddLast(TMWFuncStringObject.Create(func))
+ End Method
+
+ Rem
+ bbdoc: Clears all callback functions.
+ EndRem
+ Method Clear()
+ list.Clear()
+ End Method
+
+ Rem
+ bbdoc: Removes a callback function.
+ EndRem
+ Method Remove(func(w:TMWidget, a:String, b:Object))
+ For Local fp:TMWFuncStringObject=EachIn list
+ If fp.func=func
+ list.Remove(fp)
+ Return
+ EndIf
+ Next
+ End Method
+
+ Method Fire(w:TMWidget, a:String, b:Object)
+ For Local fp:TMWFuncStringObject=EachIn list
+ fp.func(w,a,b)
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a base managed widget type.
+EndRem
+Type TMWidget Abstract
+
+ Rem
+ bbdoc: The underlying BlitzMAX GUI Gadget
+ EndRem
+ Field gadget:TGadget
+
+ Rem
+ bbdoc: The parent of this managed widget
+ EndRem
+ Field parent:TMWidget
+
+ Rem
+ bbdoc: Children of this managed widget
+ EndRem
+ Field children:TList
+
+ Field typename:String
+ Field timer:TTimer
+
+ Method Delete()
+ FreeGadget(gadget)
+ End Method
+
+ Rem
+ bbdoc: Handles an event.
+ about: Sub-classes will generally override this to handle events directed at themselves.
+ If the event is unhandled then the event should be passed up to the parent type. @e holds the TEvent.
+ EndRem
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_MOUSEENTER
+ OnMouseEnter()
+ OnMouseEnterEvent.Fire(Self)
+ Case EVENT_MOUSELEAVE
+ OnMouseLeave()
+ OnMouseLeaveEvent.Fire(Self)
+ Case EVENT_TIMERTICK
+ OnTimer()
+ OnTimerEvent.Fire(Self)
+ End Select
+ End Method
+
+ Rem
+ bbdoc: Activate the widget (give it keyboard focus).
+ EndRem
+ Method Activate(state:Int)
+ ActivateGadget(gadget)
+ End Method
+
+ Rem
+ bbdoc: Enables/disables a widget.
+ EndRem
+ Method Enabled(state:Int)
+ If state
+ EnableGadget(gadget)
+ Else
+ DisableGadget(gadget)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Is widget enabled.
+ returns: TRUE if enabled.
+ EndRem
+ Method IsEnabled:Int()
+ Return Not GadgetDisabled(gadget)
+ End Method
+
+ Rem
+ bbdoc: Hide/show the widget.
+ EndRem
+ Method Hidden(state:Int)
+ If state
+ HideGadget(gadget)
+ Else
+ ShowGadget(gadget)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Is widget hidden.
+ returns: TRUE if hidden.
+ EndRem
+ Method IsHidden:Int()
+ Return GadgetHidden(gadget)
+ End Method
+
+ Rem
+ bbdoc: The widget's position.
+ returns: The widget's X co-ordinate.
+ EndRem
+ Method X:Int()
+ Return GadgetX(gadget)
+ End Method
+
+ Rem
+ bbdoc: The widget's position.
+ returns: The widget's Y co-ordinate.
+ EndRem
+ Method Y:Int()
+ Return GadgetY(gadget)
+ End Method
+
+ Rem
+ bbdoc: The widget's size.
+ returns: The widget's width.
+ EndRem
+ Method Width:Int()
+ Return GadgetWidth(gadget)
+ End Method
+
+ Rem
+ bbdoc: The widget's size.
+ returns: The widget's height.
+ EndRem
+ Method Height:Int()
+ Return GadgetHeight(gadget)
+ End Method
+
+ Rem
+ bbdoc: The widget's client size.
+ returns: The widget's client width.
+ EndRem
+ Method Client_Width:Int()
+ Return ClientWidth(gadget)
+ End Method
+
+ Rem
+ bbdoc: The widget's client size.
+ returns: The widget's client height.
+ EndRem
+ Method Client_Height:Int()
+ Return ClientHeight(gadget)
+ End Method
+
+ Rem
+ bbdoc: Set the widget's font.
+ EndRem
+ Method Font(font:TGUIFont)
+ SetGadgetFont(gadget,font)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's layout. See Max GUIs SetGadgetLayout() for details.
+ EndRem
+ Method Layout(Left:Int, Right:Int, top:Int, bottom:Int)
+ SetGadgetLayout(gadget,Left,Right,top,bottom)
+ End Method
+
+ Rem
+ bbdoc: Set the widget's position and size.
+ EndRem
+ Method SetShape(x:Int, y:Int, width:Int, height:Int)
+ SetGadgetShape(gadget,x,y,width,height)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's alpha.
+ EndRem
+ Method Alpha(a:Double)
+ SetGadgetAlpha(gadget,a)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's text colour.
+ EndRem
+ Method TextColour(r:Int, g:Int, b:Int)
+ SetGadgetTextColor(gadget,r,g,b)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's background colour.
+ EndRem
+ Method BackColour(r:Int, g:Int, b:Int)
+ SetGadgetColor(gadget,r,g,b)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's text.
+ EndRem
+ Method Text(s:String)
+ SetGadgetText(gadget,s)
+ End Method
+
+ Rem
+ bbdoc: Print the widget
+ EndRem
+ Method Print()
+ GadgetPrint(gadget)
+ End Method
+
+ Rem
+ bbdoc: Perform a cut on the widget
+ EndRem
+ Method Cut()
+ GadgetCut(gadget)
+ End Method
+
+ Rem
+ bbdoc: Perform a copy on the widget
+ EndRem
+ Method Copy()
+ GadgetCopy(gadget)
+ End Method
+
+ Rem
+ bbdoc: Perform a paste on the widget
+ EndRem
+ Method Paste()
+ GadgetPaste(gadget)
+ End Method
+
+ Rem
+ bbdoc: Allocates a timer for this widget.
+ about: Create a Blitz MAX TTimer that is fired @hertz times a second. When the timer pulses then @OnTimer() is called.
+ If this routine is called when a timer is already active, then the timer is re-initialised with the passed hertz.
+ EndRem
+ Method SetTimer(hertz:Double)
+ ClearTimer()
+ timer=CreateTimer(hertz,CreateEvent(EVENT_TIMERTICK,gadget))
+ End Method
+
+ Rem
+ bbdoc: Clears timer previously activated by @SetTimer().
+ EndRem
+ Method ClearTimer()
+ If timer
+ StopTimer(timer)
+ EndIf
+ timer=Null
+ End Method
+
+ Rem
+ bbdoc: Called when the widget's timer fires.
+ EndRem
+ Method OnTimer()
+ End Method
+
+ Rem
+ bbdoc: Called when the widget's timer fires.
+ EndRem
+ Field OnTimerEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the widget is managed.
+ EndRem
+ Method OnManage()
+ End Method
+
+ Rem
+ bbdoc: Called when the widget is managed.
+ EndRem
+ Field OnManageEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the widget is unmanaged.
+ EndRem
+ Method OnUnmanage()
+ End Method
+
+ Rem
+ bbdoc: Called when the widget is unmanaged.
+ EndRem
+ Field OnUnmanageEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the mouse enters.
+ EndRem
+ Method OnMouseEnter()
+ End Method
+
+ Rem
+ bbdoc: Called when the mouse enters.
+ EndRem
+ Field OnMouseEnterEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the mouse leaves.
+ EndRem
+ Method OnMouseLeave()
+ End Method
+
+ Rem
+ bbdoc: Called when the mouse leaves.
+ EndRem
+ Field OnMouseLeaveEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Fires an event at this managed widget.
+ about: The arguments are the same as @CreateEvent(), but no source is passed in.
+ EndRem
+ Method Emit(id:Int, data:Int=0, mods:Int=0, x:Int=0, y:Int=0,extra:Object=Null)
+ EmitEvent(CreateEvent(id,gadget,data,mods,x,y,extra))
+ End Method
+
+ Rem
+ bbdoc: Initialises the base managed widget stuff.
+ about: All sub-classes must call this! @gadget is the created TGadget for this instance,
+ and @parent is the parent managed widget (NULL for none).
+ EndRem
+ Method BaseInitialise(gadget:TGadget, parent:TMWidget)
+ Self.children=CreateList()
+ Self.gadget=gadget
+ Self.parent=parent
+
+ OnTimerEvent=New TMWEventListVoid
+ OnManageEvent=New TMWEventListVoid
+ OnUnmanageEvent=New TMWEventListVoid
+ OnMouseEnterEvent=New TMWEventListVoid
+ OnMouseLeaveEvent=New TMWEventListVoid
+
+ If Self.parent
+ Self.parent.children.AddLast(Self)
+ EndIf
+
+ Static.Register(Self)
+ End Method
+
+ Rem
+ bbdoc: Removes the managed widget from the internal lists.
+ about: All child objects will also be unmanaged.
+ EndRem
+ Method Unmanage()
+ Static.Deregister(Self)
+ End Method
+
+ Method ToString:String()
+ Return typename+":"+Super.ToString()
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed window.
+EndRem
+Type TMWindow Extends TMWidget
+
+ Rem
+ bbdoc: Creates a managed window.
+ returns: The created window.
+ about: @name, @x, @y, @w, @h, @group and @flags act the same as the MaxGUI arguments to @CreateWindow(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMWindow(name:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget=Null, flags:Int=15)
+ closed=False
+
+ OnMoveEvent=New TMWEventListIntInt
+ OnResizeEvent=New TMWEventListIntInt
+ OnCloseEvent=New TMWEventListVoid
+ OnDropEvent=New TMWEventListString
+
+ Local g:TGadget
+
+ If group
+ g=CreateWindow(name,x,y,w,h,group.gadget,flags)
+ Else
+ g=CreateWindow(name,x,y,w,h,Null,flags)
+ EndIf
+
+ BaseInitialise(g,group)
+ typename="TMWindow"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Set to TRUE when the window is closed (the user has pressed the close gadget).
+ EndRem
+ Field closed:Int
+
+ Rem
+ bbdoc: Activate the window.
+ EndRem
+ Method Activate(state:Int)
+ ActivateWindow(gadget)
+ End Method
+
+ Rem
+ bbdoc: Send a close event to this window.
+ EndRem
+ Method Close()
+ Emit(EVENT_WINDOWCLOSE)
+ End Method
+
+ Rem
+ bbdoc: Hide to show the window.
+ about: Note that this sets the @closed field to the @state passed in.
+ EndRem
+ Method Hidden(state:Int)
+ closed=state
+ Super.Hidden(state)
+ End Method
+
+ Rem
+ bbdoc: Set the window's status text.
+ EndRem
+ Method StatusText(text:String)
+ SetStatusText(gadget,text)
+ End Method
+
+ Rem
+ bbdoc: Set the window's minimum size.
+ EndRem
+ Method MinSize(width:Int, height:Int)
+ Return SetMinWindowSize(gadget,width,height)
+ End Method
+
+ Rem
+ bbdoc: Restore a minimizwed or maximized window.
+ EndRem
+ Method Restore()
+ Return RestoreWindow(gadget)
+ End Method
+
+ Rem
+ bbdoc: Maximize the window.
+ EndRem
+ Method Maximize()
+ Return MaximizeWindow(gadget)
+ End Method
+
+ Rem
+ bbdoc: Is the window maximized?
+ returns:TRUE if the window is maximized
+ EndRem
+ Method IsMaximized()
+ Return WindowMaximized(gadget)
+ End Method
+
+ Rem
+ bbdoc: Minimize the window.
+ EndRem
+ Method Minimize()
+ Return MinimizeWindow(gadget)
+ End Method
+
+ Rem
+ bbdoc: Is the window minimized?
+ returns:TRUE if the window is minimized
+ EndRem
+ Method IsMinimized()
+ Return WindowMinimized(gadget)
+ End Method
+
+ Rem
+ bbdoc: Called when the window is moved.
+ about:@x and @y are the new position.
+ EndRem
+ Method OnMove(x:Int, y:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the window is moved.
+ EndRem
+ Field OnMoveEvent:TMWEventListIntInt
+
+ Rem
+ bbdoc: Called when the window is resized.
+ about:@width and @height are the new size.
+ EndRem
+ Method OnResize(width:Int, height:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the window is resized.
+ EndRem
+ Field OnResizeEvent:TMWEventListIntInt
+
+ Rem
+ bbdoc: Called when the window's close gadget is pressed.
+ about: This default implementation sets @closed to TRUE and hide the window if no events are defined in @OnCloseEvent.
+ EndRem
+ Method OnClose()
+ If Not OnCloseEvent.list.Count()
+ closed=True
+ Hidden(True)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Called when the window's close gadget is pressed.
+ EndRem
+ Field OnCloseEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when a file is dropped in the window.
+ about: @path is the dropped file.
+ EndRem
+ Method OnDrop(path:String)
+ End Method
+
+ Rem
+ bbdoc: Called when a file is dropped in the window.
+ EndRem
+ Field OnDropEvent:TMWEventListString
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_WINDOWACCEPT
+ OnDrop(String(e.extra))
+ OnDropEvent.Fire(Self,String(e.extra))
+ Case EVENT_WINDOWMOVE
+ OnMove(e.x,e.y)
+ OnMoveEvent.Fire(Self,e.x,e.y)
+ Case EVENT_WINDOWSIZE
+ OnResize(e.x,e.y)
+ OnResizeEvent.Fire(Self,e.x,e.y)
+ Case EVENT_WINDOWCLOSE
+ OnClose()
+ OnCloseEvent.Fire(Self)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed button push button.
+EndRem
+Type TMButton Extends TMWidget
+
+ Rem
+ bbdoc: Creates a managed push button.
+ returns: The created button.
+ about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ OnPressEvent=New TMWEventListVoid
+ BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_PUSH),group)
+ typename="TMButton"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Creates a managed push button used for an OK button
+ returns: The created button.
+ about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
+ EndRem
+ Method CreateOK:TMButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ OnPressEvent=New TMWEventListVoid
+ BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_OK),group)
+ typename="TMButton"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Creates a managed push button used for a Cancel button
+ returns: The created button.
+ about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
+ EndRem
+ Method CreateCancel:TMButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ OnPressEvent=New TMWEventListVoid
+ BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_OK),group)
+ typename="TMButton"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Called when the button is pressed.
+ EndRem
+ Method OnPress()
+ End Method
+
+ Rem
+ bbdoc: Called when the button is pressed.
+ EndRem
+ Field OnPressEvent:TMWEventListVoid
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnPress()
+ OnPressEvent.Fire(Self)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed checkbox.
+EndRem
+Type TMCheckbox Extends TMWidget
+ Rem
+ bbdoc: Creates a managed checkbox.
+ returns: The created checkbox.
+ about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMCheckbox(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ OnPressEvent=New TMWEventListInt
+ BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_CHECKBOX),group)
+ typename="TMCheckbox"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Sets the state of the check.
+ EndRem
+ Method Checked(check:Int)
+ SetButtonState(gadget,check)
+ End Method
+
+ Rem
+ bbdoc: Is the checkbox checked?
+ returns:TRUE if the checkbox is checked.
+ EndRem
+ Method IsChecked()
+ Return ButtonState(gadget)
+ End Method
+
+ Rem
+ bbdoc: Called when the checkbox is pressed.
+ about: @checked is the current state.
+ EndRem
+ Method OnPress(checked:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the checkbox is pressed.
+ EndRem
+ Field OnPressEvent:TMWEventListInt
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnPress(e.data)
+ OnPressEvent.Fire(Self,e.data)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed radio button.
+EndRem
+Type TMRadioButton Extends TMCheckbox
+ Field set:TMRadioButtonSet
+
+ Rem
+ bbdoc: Creates a managed radio button.
+ returns: The created radio button.
+ about: @label, @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateButton(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMRadioButton(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ OnPressEvent=New TMWEventListInt
+ BaseInitialise(CreateButton(label,x,y,w,h,group.gadget,BUTTON_RADIO),group)
+ typename="TMRadioButton"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Called when the checkbox is pressed.
+ about: @checked is the current state. In this default implementation the @TMRadioButtonSet which this button belongs too will fire
+ its @OnSelected() member.
+ EndRem
+ Method OnPress(checked:Int)
+ If set
+ set.ButtonFired(Self)
+ EndIf
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a set of managed radio button.
+EndRem
+Type TMRadioButtonSet
+ Field but:TMRadioButton[]
+
+ Rem
+ bbdoc: Creates a set of managed radio buttons.
+ returns: The created set.
+ about: The radio buttons must have been created prior to calling this.
+ EndRem
+ Method Create:TMRadioButtonSet(buttons:TMRadioButton[])
+ OnSelectedEvent=New TMWEventListInt
+ but=buttons
+ For Local b:TMRadioButton=EachIn but
+ b.set=Self
+ Next
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Sets the active radio button.
+ about: @index is the index of the button to set.
+ EndRem
+ Method Set(index:Int)
+ but[index].Checked(True)
+ End Method
+
+ Rem
+ bbdoc: If using the base TMRadioButton implmentation this will be called when the buttons change.
+ about: @index is the selected button.
+ EndRem
+ Method OnSelected(index:Int)
+ End Method
+
+ Rem
+ bbdoc: If using the base TMRadioButton implmentation this will be called when the buttons change.
+ about: The radio button that fired will be passed into the event.
+ EndRem
+ Field OnSelectedEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Get the active radio button.
+ returns: The index of the button set. -1 if no button is set.
+ EndRem
+ Method Current()
+ For Local f:Int=0 Until but.length
+ If but[f].IsChecked()
+ Return f
+ EndIf
+ Next
+ Return -1
+ End Method
+
+ Method ButtonFired(b:TMRadioButton)
+ For Local f:Int=0 Until but.length
+ If but[f]=b
+ OnSelected(f)
+ OnSelectedEvent.Fire(b,f)
+ Return
+ EndIf
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed label.
+EndRem
+Type TMLabel Extends TMWidget
+
+ Rem
+ bbdoc: Creates a managed label.
+ returns: The created label.
+ about: @label, @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateLabel(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMLabel(label:String, x:Int,y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ BaseInitialise(CreateLabel(label,x,y,w,h,group.gadget,style),group)
+ typename="TMLabel"
+ Return Self
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed text field.
+EndRem
+Type TMTextField Extends TMWidget
+ Rem
+ bbdoc: Creates a managed text field.
+ returns: The created text field.
+ about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateTextField(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMTextField(x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ OnTextChangedEvent=New TMWEventListString
+ BaseInitialise(CreateTextField(x,y,w,h,group.gadget),group)
+ typename="TMTextField"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Creates a managed text field for entering passwords.
+ returns: The created text field.
+ about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateTextField(), except that @group is a TMWidget.
+ EndRem
+ Method CreateSecret:TMTextField(x:Int,y:Int, w:Int, h:Int, group:TMWidget)
+ BaseInitialise(CreateTextField(x,y,w,h,group.gadget,TEXTFIELD_PASSWORD),group)
+ typename="TMTextField"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: The field's text.
+ returns:The text.
+ EndRem
+ Method GetText:String()
+ Return TextFieldText(gadget)
+ End Method
+
+ Rem
+ bbdoc: Called when the text changes.
+ about: @txt is the content of the field
+ EndRem
+ Method OnTextChanged(txt:String)
+ End Method
+
+ Rem
+ bbdoc: Called when the text changes.
+ EndRem
+ Field OnTextChangedEvent:TMWEventListString
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ Local s:String=TextFieldText(gadget)
+ OnTextChanged(s)
+ OnTextChangedEvent.Fire(Self,s)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed text area.
+EndRem
+Type TMTextArea Extends TMWidget
+ Rem
+ bbdoc: Creates a managed text area.
+ returns: The created text area.
+ about: @x, @y, @w, @h,, @group and @style act the same as the MaxGUI arguments to @CreateTextArea(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMTextArea(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ OnTextChangedEvent=New TMWEventListVoid
+ OnSelectionEvent=New TMWEventListVoid
+ OnMenuEvent=New TMWEventListVoid
+ BaseInitialise(CreateTextArea(x,y,w,h,group.gadget,style),group)
+ typename="TMTextArea"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: The text area's text.
+ returns:The text.
+ EndRem
+ Method GetText:String(pos:Int=0, length:Int=TEXTAREA_ALL, units:Int=TEXTAREA_CHARS)
+ Return TextAreaText(gadget,pos,length,units)
+ End Method
+
+ Rem
+ bbdoc: Set the widget's font.
+ EndRem
+ Method Font(font:TGUIFont)
+ SetTextAreaFont(gadget,font)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's text colour.
+ EndRem
+ Method TextColour(r:Int, g:Int, b:Int)
+ SetTextAreaColor(gadget,r,g,b,False)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's background colour.
+ EndRem
+ Method BackColour(r:Int, g:Int, b:Int)
+ SetTextAreaColor(gadget,r,g,b,True)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's text.
+ EndRem
+ Method Text(s:String)
+ SetText(s)
+ End Method
+
+ Rem
+ bbdoc: Set the widgets's text (see the MaxGUI docs for argument details)
+ EndRem
+ Method SetText(s:String, pos:Int=0, length:Int=TEXTAREA_ALL, units:Int=TEXTAREA_CHARS)
+ SetTextAreaText(gadget,s,pos,length,units)
+ End Method
+
+ Rem
+ bbdoc: Set the text area's tab size
+ EndRem
+ Method SetTabSize(size:Int)
+ SetTextAreaTabs(gadget,size)
+ End Method
+
+ Rem
+ bbdoc: Get the character position of the specified line.
+ EndRem
+ Method GetCharPos:Int(line:Int)
+ Return TextAreaChar(gadget,line)
+ End Method
+
+ Rem
+ bbdoc: Get the cursor's column.
+ EndRem
+ Method GetCursorColumn:Int()
+ Return TextAreaCursor(gadget,TEXTAREA_CHARS)
+ End Method
+
+ Rem
+ bbdoc: Get the cursor's row.
+ EndRem
+ Method GetCursorRow:Int()
+ Return TextAreaCursor(gadget,TEXTAREA_LINES)
+ End Method
+
+ Rem
+ bbdoc: Get the text length.
+ EndRem
+ Method GetLength:Int()
+ Return TextAreaLen(gadget)
+ End Method
+
+ Rem
+ bbdoc: Get the selected texts length.
+ EndRem
+ Method GetSelectionLength:Int()
+ Return TextAreaSelLen(gadget,TEXTAREA_CHARS)
+ End Method
+
+ Rem
+ bbdoc: Get the number of selected rows.
+ EndRem
+ Method GetSelectionRows:Int()
+ Return TextAreaSelLen(gadget,TEXTAREA_LINES)
+ End Method
+
+ Rem
+ bbdoc: Lock the text area.
+ EndRem
+ Method Lock()
+ Return LockTextArea(gadget)
+ End Method
+
+ Rem
+ bbdoc: Unlock the text area.
+ EndRem
+ Method Unlock()
+ Return UnlockTextArea(gadget)
+ End Method
+
+ Rem
+ bbdoc: Set the format. See the MaxGUI docs for details.
+ EndRem
+ Method Format(r:Int, g:Int, b:Int, flags:Int, pos:Int=0, length:Int=TEXTAREA_ALL, units:Int=TEXTAREA_CHARS )
+ FormatTextAreaText(gadget,r,g,b,flags,pos,length,units)
+ End Method
+
+ Rem
+ bbdoc: Called when the text changes.
+ EndRem
+ Method OnTextChanged()
+ End Method
+
+ Rem
+ bbdoc: Called when the text changes.
+ EndRem
+ Field OnTextChangedEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the selection or cursor changes.
+ EndRem
+ Method OnSelection()
+ End Method
+
+ Rem
+ bbdoc: Called when the selection or cursor changes.
+ EndRem
+ Field OnSelectionEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the context menu is requested.
+ EndRem
+ Method OnMenu()
+ End Method
+
+ Rem
+ bbdoc: Called when the context menu is requested.
+ EndRem
+ Field OnMenuEvent:TMWEventListVoid
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnTextChanged()
+ OnTextChangedEvent.Fire(Self)
+ Case EVENT_GADGETSELECT
+ OnSelection()
+ OnSelectionEvent.Fire(Self)
+ Case EVENT_GADGETMENU
+ OnMenu()
+ OnMenuEvent.Fire(Self)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed slider.
+EndRem
+Type TMSlider Extends TMWidget
+ Rem
+ bbdoc: Creates a managed slider.
+ returns: The created slider.
+ about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateSlider(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMSlider(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ OnValueChangedEvent=New TMWEventListInt
+ BaseInitialise(CreateSlider(x,y,w,h,group.gadget,style),group)
+ typename="TMSlider"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Set the sliders's min/max values.
+ about: See the MaxGUI docs for how this affects scrollbar style sliders.
+ EndRem
+ Method SetRange(range0:Int,range1:Int)
+ Return SetSliderRange(gadget,range0,range1)
+ End Method
+
+ Rem
+ bbdoc: Set the sliders's value.
+ EndRem
+ Method SetValue(value:Int)
+ Return SetSliderValue(gadget,value)
+ End Method
+
+ Rem
+ bbdoc: The sliders's value.
+ returns:The value.
+ EndRem
+ Method GetValue:Int()
+ Return SliderValue(gadget)
+ End Method
+
+ Rem
+ bbdoc: Called when the slider moves.
+ about: @val is the new slider value.
+ EndRem
+ Method OnValueChanged(val:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the slider moves.
+ EndRem
+ Field OnValueChangedEvent:TMWEventListInt
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnValueChanged(e.data)
+ OnValueChangedEvent.Fire(Self,e.data)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines an entry in a list style gadget.
+about: Always use @CreateListEntry() to create this object.
+EndRem
+Type TMListEntry
+ Rem
+ bbdoc: The text associated with a list entry.
+ EndRem
+ Field text:String
+ Rem
+ bbdoc: The flags associated with a list entry.
+ EndRem
+ Field flags:Int
+ Rem
+ bbdoc: The icon associated with a list entry.
+ EndRem
+ Field icon:Int
+ Rem
+ bbdoc: The tooltip associated with a list entry.
+ EndRem
+ Field tip:String
+ Rem
+ bbdoc: The extra object associated with a list entry.
+ EndRem
+ Field extra:Object
+
+ Function Create:TMListEntry(text:String,flags:Int,icon:Int,tip:String,extra:Object)
+ Local o:TMListEntry=New TMListEntry
+ o.text=text
+ o.flags=flags
+ o.icon=icon
+ o.tip=tip
+ o.extra=extra
+ Return o
+ End Function
+End Type
+
+
+Rem
+bbdoc: Creates a list entry.
+returns: The list entry.
+about: @text, @flags, @icon, @tip and @extra are the fields detailed in MaxGUI @AddGadgetItem().
+EndRem
+Function CreateListEntry:TMListEntry(text:String,flags:Int=0,icon:Int=-1,tip:String="",extra:Object=Null)
+ Return TMListEntry.Create(text,flags,icon,tip,extra)
+End Function
+
+
+Rem
+bbdoc: Defines a base for list style gadgets.
+EndRem
+Type TMListWidget Extends TMWidget Abstract
+ Rem
+ bbdoc: Removes all items from the list.
+ EndRem
+ Method Clear()
+ ClearGadgetItems(gadget)
+ End Method
+
+ Rem
+ bbdoc: Adds an item to the list.
+ EndRem
+ Method AddItem(entry:TMListEntry)
+ AddGadgetItem(gadget,entry.text,entry.flags,entry.icon,entry.tip,entry.extra)
+ End Method
+
+ Rem
+ bbdoc: Adds items to the list.
+ EndRem
+ Method AddItems(entry:TMListEntry[])
+ For Local f:Int=0 Until entry.length
+ AddItem(entry[f])
+ Next
+ End Method
+
+ Rem
+ bbdoc: Modify an item in the list.
+ EndRem
+ Method ModifyItem(index:Int, entry:TMListEntry)
+ ModifyGadgetItem(gadget,index,entry.text,entry.flags,entry.icon,entry.tip,entry.extra)
+ End Method
+
+ Rem
+ bbdoc: Set an icon strip for the list.
+ EndRem
+ Method SetIconStrip(icons:TIconStrip)
+ SetGadgetIconStrip(gadget,icons)
+ End Method
+
+ Rem
+ bbdoc: Get an item from the list.
+ about: Note that the @tip field is not set on return
+ EndRem
+ Method GetItem:TMListEntry(index:Int)
+ Return CreateListEntry(GadgetItemText(gadget,index), ..
+ GadgetItemFlags(gadget,index), ..
+ GadgetItemIcon(gadget,index), ..
+ "", ..
+ GadgetItemExtra(gadget,index))
+ End Method
+
+ Rem
+ bbdoc: Enable or disable a particular item.
+ EndRem
+ Method ItemEnabled(index:Int, state:Int)
+ If state
+ EnableGadgetItem(gadget,index)
+ Else
+ DisableGadgetItem(gadget,index)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Set the currently selected item.
+ EndRem
+ Method SetSelectedIndex(index:Int)
+ SelectGadgetItem(gadget,index)
+ End Method
+
+ Rem
+ bbdoc: Get the index of the first selected item.
+ EndRem
+ Method SelectedIndex:Int()
+ Return SelectedGadgetItem(gadget)
+ End Method
+
+ Rem
+ bbdoc: Get the indexes of the selected items.
+ EndRem
+ Method SelectedIndexes:Int[]()
+ Return SelectedGadgetItems(gadget)
+ End Method
+
+ Rem
+ bbdoc: Get the first selected item, NULL if nothing selected.
+ EndRem
+ Method SelectedItem:TMListEntry()
+ If SelectedIndex()=-1
+ Return Null
+ EndIf
+
+ Return GetItem(SelectedIndex())
+ End Method
+
+ Rem
+ bbdoc: Get the selected items, NULL if nothing selected.
+ EndRem
+ Method SelectedItems:TMListEntry[]()
+ If SelectedIndex()=-1
+ Return Null
+ EndIf
+
+ Local sel:Int[]=SelectedIndexes()
+ Local ret:TMListEntry[]=New TMListEntry[sel.length]
+
+ For Local f:Int=0 Until sel.length
+ ret[f]=GetItem(sel[f])
+ Next
+ Return ret
+ End Method
+
+ Rem
+ bbdoc: Called when the selection changes.
+ about: @index is the selected index. This can be -1 for no selection.
+ EndRem
+ Method OnIndexChanged(index:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the selection changes.
+ EndRem
+ Field OnIndexChangedEvent:TMWEventListInt
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnIndexChanged(e.data)
+ OnIndexChangedEvent.Fire(Self,e.data)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed combo box.
+EndRem
+Type TMComboBox Extends TMListWidget
+ Rem
+ bbdoc: Creates a managed combo box.
+ returns: The created combo box.
+ about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateComboBox(), except that @group is a TMWidget.
+ If @values is not NULL it is used to load up the initial options.
+ <b>IMPORTANT</b>: It is really not recommended to use COMBOBOX_EDITABLE as OnIndexChanged() is called when the user edits the field.
+ There seems to be no easy way to remedy this.
+ EndRem
+ Method Create:TMComboBox(x:Int,y:Int, w:Int, h:Int, group:TMWidget, style:Int=0, values:TMListEntry[]=Null)
+ OnIndexChangedEvent=New TMWEventListInt
+ BaseInitialise(CreateComboBox(x,y,w,h,group.gadget,style),group)
+ typename="TMComboBox"
+ If values
+ AddItems(values)
+ EndIf
+ Return Self
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed list box.
+EndRem
+Type TMListBox Extends TMListWidget
+ Rem
+ bbdoc: Creates a managed list box.
+ returns: The created list box.
+ about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateListBox(), except that @group is a TMWidget.
+ If @values is not NULL it is used to load up the initial options.
+ EndRem
+ Method Create:TMListBox(x:Int,y:Int, w:Int, h:Int, group:TMWidget, values:TMListEntry[]=Null)
+ OnIndexChangedEvent=New TMWEventListInt
+ BaseInitialise(CreateListBox(x,y,w,h,group.gadget),group)
+ typename="TMListBox"
+ If values
+ AddItems(values)
+ EndIf
+ Return Self
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed tabber.
+EndRem
+Type TMTabber Extends TMListWidget
+ Field pages:TMWidget[][]
+
+ Rem
+ bbdoc: Creates a managed tabber.
+ returns: The created tabber.
+ about: @x, @y, @w, @h, and @group act the same as the MaxGUI arguments to @CreateTabber(), except that @group is a TMWidget.
+ If @values is not NULL it is used to load up the initial options.
+ EndRem
+ Method Create:TMTabber(x:Int,y:Int, w:Int, h:Int, group:TMWidget, values:TMListEntry[]=Null)
+ OnIndexChangedEvent=New TMWEventListInt
+ BaseInitialise(CreateTabber(x,y,w,h,group.gadget),group)
+ typename="TMTabber"
+ If values
+ AddItems(values)
+ EndIf
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Defines the gadgets to appear on each page of the tabber.
+ about: @widgets is an array of @TMWidget arrays. Each sub-array is one page.
+ EndRem
+ Method SetPages(widgets:TMWidget[][])
+ pages=widgets
+ End Method
+
+ Rem
+ bbdoc: Set the currently selected page.
+ about: This will hide/show the widgets defined by @DefinePages() as appropriate.
+ EndRem
+ Method SetSelectedIndex(index:Int)
+ SelectGadgetItem(gadget,index)
+
+ If pages
+ For Local f:Int=0 Until pages.length
+ For Local w:TMWidget=EachIn pages[f]
+ w.Hidden(f<>index)
+ Next
+ Next
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: This default implementation will switch the widgets as defined by @DefinePages()
+ EndRem
+ Method OnIndexChanged(index:Int)
+ If index>-1 And pages
+ For Local f:Int=0 Until pages.length
+ For Local w:TMWidget=EachIn pages[f]
+ w.Hidden(f<>index)
+ Next
+ Next
+ EndIf
+ End Method
+
+End Type
+
+
+Rem
+bbdoc: Defines a managed HTML View.
+EndRem
+Type TMHTMLView Extends TMWidget
+ Rem
+ bbdoc: Creates a managed HTML View.
+ returns: The created HTML View.
+ about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateHMTLView(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMHTMLView(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ OnPageLoadedEvent=New TMWEventListString
+ OnSelectURLEvent=New TMWEventListString
+ BaseInitialise(CreateHTMLView(x,y,w,h,group.gadget,style),group)
+ typename="TMHTMLView"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: The current URL.
+ EndRem
+ Method CurrentURL:String()
+ Return HtmlViewCurrentURL(gadget)
+ End Method
+
+ Rem
+ bbdoc: Enter the URL to goto.
+ EndRem
+ Method Go(url:String)
+ HtmlViewGo(gadget,url)
+ End Method
+
+ Rem
+ bbdoc: Go back in the history.
+ EndRem
+ Method Back()
+ HtmlViewBack(gadget)
+ End Method
+
+ Rem
+ bbdoc: Go forward in the history.
+ EndRem
+ Method Forward()
+ HtmlViewForward(gadget)
+ End Method
+
+ Rem
+ bbdoc:Run a script.
+ EndRem
+ Method RunScript:String(script:String)
+ HtmlViewRun(gadget,script)
+ End Method
+
+ Rem
+ bbdoc: If HTMLVIEW_NONAVIGATE is set in the styles, then this is called when a link is clicked.
+ about: @url is the selected URL.
+ EndRem
+ Method OnSelectURL(url:String)
+ End Method
+
+ Rem
+ bbdoc: If HTMLVIEW_NONAVIGATE is set in the styles, then this is called when a link is clicked.
+ EndRem
+ Field OnSelectURLEvent:TMWEventListString
+
+ Rem
+ bbdoc: Called when the page finishes loading.
+ about: @url is the loaded URL.
+ EndRem
+ Method OnPageLoaded(url:String)
+ End Method
+
+ Rem
+ bbdoc: Called when the page finishes loading.
+ EndRem
+ Field OnPageLoadedEvent:TMWEventListString
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnSelectURL(e.extra.ToString())
+ OnSelectURLEvent.Fire(Self,e.extra.ToString())
+ Case EVENT_GADGETDONE
+ OnPageLoaded(CurrentURL())
+ OnPageLoadedEvent.Fire(Self,CurrentURL())
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Type TMTreeNode
+ Field path:String
+ Field node:TGadget
+ Field tag:Object
+ Field icon:Int
+ Function Create:TMTreeNode(path:String, node:TGadget, tag:Object, icon:Int)
+ Local o:TMTreeNode=New TMTreeNode
+ o.path=path
+ o.node=node
+ o.tag=tag
+ o.icon=icon
+ Return o
+ End Function
+End Type
+
+Rem
+bbdoc: Defines a managed tree view.
+about: The tree view works by treating its entries as if in a simple file system.
+EndRem
+Type TMTreeView Extends TMWidget
+ Field map:TMap
+ Field gmap:TMap
+ Field update:Int
+
+ Rem
+ bbdoc: Creates a managed tree view.
+ returns: The created tree view.
+ about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateTreeView(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMTreeView(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ update=False
+ map=New TMap
+ gmap=New TMap
+ OnSelectedEvent=New TMWEventListStringObject
+ OnClickedEvent=New TMWEventListStringObject
+ OnMenuEvent=New TMWEventListStringObject
+ OnExpandedEvent=New TMWEventListStringObject
+ OnCollapsedEvent=New TMWEventListStringObject
+ BaseInitialise(CreateTreeView(x,y,w,h,group.gadget,style),group)
+ typename="TMNodeView"
+ map.Insert("/",TMTreeNode.Create("/",TreeViewRoot(gadget),"/",-1))
+ Return Self
+ End Method
+
+ Method ResolvePath:TMTreeNode(path:String)
+ Return TMTreeNode(map.ValueForKey(path))
+ End Method
+
+ Method ResolveGadget:TMTreeNode(g:TGadget)
+ Return ResolvePath(gmap.ValueForKey(g).ToString())
+ End Method
+
+ Method Prune(path:String)
+ Local l:TList=CreateList()
+
+ ' Not sure if this is overly ineffecient -- just being safe as in most languages deleting whilst iterating
+ ' is not recommended...
+ '
+ For Local k:String=EachIn map.Keys()
+ If k=path Or k.Find(path+"/")=0
+ l.AddLast(k)
+ EndIf
+ Next
+
+ For Local k:String=EachIn l
+ Local n:TMTreeNode=ResolvePath(k)
+ map.Remove(k)
+ gmap.Remove(n.node)
+ Next
+ End Method
+
+ Rem
+ bbdoc: Set an icon strip.
+ EndRem
+ Method SetIconStrip(icons:TIconStrip)
+ SetGadgetIconStrip(gadget,icons)
+ End Method
+
+ Rem
+ bbdoc: The number of nodes in the view that are direct children on the passed node.
+ returns: The number of nodes.
+ about: @path is the path to count from. Unfortunately counting from the root (/) doesn't work, so it returns -1.
+ EndRem
+ Method CountChildren:Int(path:String)
+ If path="/"
+ Return -1
+ EndIf
+
+ Local node:TMTreeNode=ResolvePath(path)
+
+ If node
+ Return CountTreeViewNodes(node.node)
+ Else
+ Return 0
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Remove nodes from the tree.
+ about: Attempting to remove the root node (/) will fail.
+ EndRem
+ Method Remove(path:String)
+ If path<>"/"
+ Local node:TMTreeNode=ResolvePath(path)
+
+ If node
+ FreeTreeViewNode(node.node)
+ Prune(path)
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Don't redraw gadget when adding nodes.
+ EndRem
+ Method BeginUpdate()
+ update=True
+ End Method
+
+
+ Rem
+ bbdoc: Allow redraw of gadget when adding nodes.
+ EndRem
+ Method EndUpdate()
+ update=False
+ End Method
+
+
+ Rem
+ bbdoc: Add/modify nodes in the tree.
+ about: @path is the path to the node. This silently fails if the parent nodes don't exist. @tag is an Object that the entry is tagged with.
+ ToString() is called on this to create the text for the entry (so passing a String works fine).
+ @icon is the icon to use. Note that if you set an icon strip, then this seems to use the first icon (on Win32 at least) if set to -1.
+ EndRem
+ Method Set(path:String, tag:Object, icon:Int=-1)
+ Local parent:TMTreeNode=ResolvePath(FixedExtractDir(path))
+
+ If parent
+ Local node:TMTreeNode=ResolvePath(path)
+
+ If node
+ ModifyTreeViewNode(node.node,tag.ToString(),icon)
+ Else
+ node=TMTreeNode.Create(path,AddTreeViewNode(tag.ToString(),parent.node,icon),tag,icon)
+ map.Insert(path,node)
+ gmap.Insert(node.node,path)
+ EndIf
+
+ node.tag=tag
+ node.icon=icon
+
+ If Not update
+ RedrawGadget(gadget)
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Get the tag at a node.
+ returns: The tag, or NULL for unknown node.
+ EndRem
+ Method GetNodeTag:Object(path:String)
+ Local node:TMTreeNode=ResolvePath(path)
+ If node
+ Return node.tag
+ Else
+ Return Null
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Get the icon at a node.
+ returns: The icon, or -1 for none or unknown node.
+ EndRem
+ Method GetNodeIcon:Int(path:String)
+ Local node:TMTreeNode=ResolvePath(path)
+ If node
+ Return node.icon
+ Else
+ Return -1
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Expand a node on the tree.
+ EndRem
+ Method ExpandNode(path:String)
+ Local node:TMTreeNode=ResolvePath(path)
+
+ If node
+ ExpandTreeViewNode(node.node)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Collapse a node on the tree.
+ EndRem
+ Method CollapseNode(path:String)
+ Local node:TMTreeNode=ResolvePath(path)
+
+ If node
+ CollapseTreeViewNode(node.node)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is selected.
+ about: @path is the path to the selected item, @tag is the tag for that item.
+ EndRem
+ Method OnSelected(path:String, tag:Object)
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is selected.
+ EndRem
+ Field OnSelectedEvent:TMWEventListStringObject
+
+ Rem
+ bbdoc: Called when the an item is double clicked.
+ about: @path is the path to the selected item, @tag is the tag for that item.
+ EndRem
+ Method OnClicked(path:String, tag:Object)
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is double clicked.
+ EndRem
+ Field OnClickedEvent:TMWEventListStringObject
+
+ Rem
+ bbdoc: Called when the a context menu is requested.
+ about: @path is the path to the selected item, @tag is the tag for that item.
+ EndRem
+ Method OnMenu(path:String, tag:Object)
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is selected.
+ EndRem
+ Field OnMenuEvent:TMWEventListStringObject
+
+ Rem
+ bbdoc: Called when a node is expanded.
+ about: @path is the path to the selected item, @tag is the tag for that item.
+ EndRem
+ Method OnExpanded(path:String, tag:Object)
+ End Method
+
+ Rem
+ bbdoc: Called when a node is expanded.
+ EndRem
+ Field OnExpandedEvent:TMWEventListStringObject
+
+ Rem
+ bbdoc: Called when a node is collapsed.
+ about: @path is the path to the selected item, @tag is the tag for that item.
+ EndRem
+ Method OnCollapsed(path:String, tag:Object)
+ End Method
+
+ Rem
+ bbdoc: Called when a node is collapsed.
+ EndRem
+ Field OnCollapsedEvent:TMWEventListStringObject
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETSELECT
+ Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
+ If n
+ OnSelected(n.path,n.tag)
+ OnSelectedEvent.Fire(Self,n.path,n.tag)
+ EndIf
+ Case EVENT_GADGETACTION
+ Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
+ If n
+ OnClicked(n.path,n.tag)
+ OnClickedEvent.Fire(Self,n.path,n.tag)
+ EndIf
+ Case EVENT_GADGETOPEN
+ Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
+ If n
+ OnExpanded(n.path,n.tag)
+ OnExpandedEvent.Fire(Self,n.path,n.tag)
+ EndIf
+ Case EVENT_GADGETCLOSE
+ Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
+ If n
+ OnCollapsed(n.path,n.tag)
+ OnCollapsedEvent.Fire(Self,n.path,n.tag)
+ EndIf
+ Case EVENT_GADGETMENU
+ Local n:TMTreeNode=ResolveGadget(TGadget(e.extra))
+ If n
+ OnMenu(n.path,n.tag)
+ OnMenuEvent.Fire(Self,n.path,n.tag)
+ EndIf
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Type TMenuItem
+ Field id:Int
+ Field owner:TMMenu
+ Field path:String
+ Field tag:Object
+ Field gadget:TGadget
+ Field callback(menu:TMMenu, path:String, tag:Object)
+ Function Create:TMenuItem(owner:TMMenu, id:Int, path:String, gadget:TGadget, tag:Object, callback(menu:TMMenu, path:String, tag:Object))
+ Local o:TMenuItem=New TMenuItem
+ o.owner=owner
+ o.id=id
+ o.path=path
+ o.gadget=gadget
+ o.tag=tag
+ o.callback=callback
+ Return o
+ End Function
+End Type
+
+
+Rem
+bbdoc: Defines a managed menu.
+about: Note that TMMenu is <b>NOT</b> a TMWidget.
+EndRem
+Type TMMenu
+
+ Field root:TGadget
+ Field map:TMap
+ Field win:TMWindow
+
+ Rem
+ bbdoc: Creates a managed menu that is associated as a window menu.
+ returns: The created menu.
+ about: @window is the window the menu is attached to.
+ EndRem
+ Method CreateWindowMenu:TMMenu(window:TMWindow)
+ map=New TMap
+ root=WindowMenu(window.gadget)
+ win=window
+ SetRoot()
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Creates a managed menu that can be used as a popup menu.
+ returns: The created menu.
+ EndRem
+ Method CreatePopupMenu:TMMenu()
+ map=New TMap
+ root=CreateMenu("",0,Null)
+ win=Null
+ SetRoot()
+ Return Self
+ End Method
+
+ Method Delete()
+ Clear()
+ If Not win
+ FreeMenu(root)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Clear all items from the menu
+ EndRem
+ Method Clear()
+ For Local m:TMenuItem=EachIn TMapEnumerator(MapValues(map))
+ FreeMenu(m.gadget)
+ Static.DeregisterMenuItem(m)
+ Next
+ map.Clear()
+ SetRoot()
+ End Method
+
+ Method SetRoot()
+ map.Insert("/",TMenuItem.Create(Self,0,"/",root,Null,Null))
+ End Method
+
+ Method ResolvePath:TMenuItem(path:String)
+ Return TMenuItem(map.ValueForKey(path))
+ End Method
+
+ Method Prune(path:String)
+ Local l:TList=CreateList()
+
+ ' Not sure if this is overly ineffecient -- just being safe as in most languages deleting whilst iterating
+ ' is not recommended...
+ '
+ For Local k:String=EachIn map.Keys()
+ If k=path Or k.Find(path+"/")=0
+ l.AddLast(k)
+ EndIf
+ Next
+
+ For Local k:String=EachIn l
+ Local n:TMenuItem=ResolvePath(k)
+ map.Remove(k)
+ Static.DeregisterMenuItem(n)
+ FreeMenu(n.gadget)
+ Next
+ End Method
+
+ Rem
+ bbdoc: Add a menu option.
+ about: @path is the path to the menu item. This silently fails if the parent menus don't exist. @tag is an Object that the entry is tagged with.
+ ToString() is called on this to create the text for the menu (so passing a String works fine). If @callback is not null, then it is called when
+ this option is selected.
+ @hotkey and @modifier are as in MaxGUI's CreateMenu().
+ EndRem
+ Method Set(path:String, tag:Object, callback(menu:TMMenu, path:String, tag:Object)=Null, hotkey:Int=0, modifier:Int=0)
+ If path<>"/"
+ Local parent:TMenuItem=ResolvePath(FixedExtractDir(path))
+
+ If parent
+ Local node:TMenuItem=ResolvePath(path)
+
+ If node
+ SetMenuText(node.gadget,tag.ToString())
+ Else
+ Local id:Int=Static.NextMenuID()
+ node=TMenuItem.Create(Self,id,path,CreateMenu(tag.ToString(),id,parent.gadget,hotkey,modifier),tag,callback)
+ map.Insert(path,node)
+ Static.RegisterMenuItem(node)
+ EndIf
+
+ node.tag=tag
+
+ If win
+ UpdateWindowMenu(win.gadget)
+ EndIf
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Remove menu item and its children.
+ about: @path is the path to the menu item. Root cannot be removed.
+ EndRem
+ Method Remove(path:String)
+ If path<>"/"
+ Prune(path)
+
+ If win
+ UpdateWindowMenu(win.gadget)
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Change a menu tag (and therefore its text).
+ about: @path is the path to the menu item. Root cannot be changed.
+ EndRem
+ Method SetTag(path:String, tag:Object)
+ If path<>"/"
+ Local node:TMenuItem=ResolvePath(path)
+
+ If node
+ SetMenuText(node.gadget,tag.ToString())
+ node.tag=tag
+
+ If win
+ UpdateWindowMenu(win.gadget)
+ EndIf
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Change a menu check.
+ about: @path is the path to the menu item. Root cannot be changed.
+ EndRem
+ Method Check(path:String, check:Int)
+ If path<>"/"
+ Local node:TMenuItem=ResolvePath(path)
+
+ If node
+ If check
+ CheckMenu(node.gadget)
+ Else
+ UncheckMenu(node.gadget)
+ EndIf
+
+ If win
+ UpdateWindowMenu(win.gadget)
+ EndIf
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ about: Is a menu item checked.
+ EndRem
+ Method IsChecked:Int(path:String)
+ Local ret:Int=False
+
+ If path<>"/"
+ Local node:TMenuItem=ResolvePath(path)
+
+ If node
+ ret=MenuChecked(node.gadget)
+ EndIf
+ EndIf
+
+ Return ret
+ End Method
+
+ Rem
+ bbdoc: Enable/disable a menu item.
+ about: @path is the path to the menu item. Root cannot be changed.
+ EndRem
+ Method Enable(path:String, enab:Int)
+ If path<>"/"
+ Local node:TMenuItem=ResolvePath(path)
+
+ If node
+ If enab
+ EnableMenu(node.gadget)
+ Else
+ DisableMenu(node.gadget)
+ EndIf
+
+ If win
+ UpdateWindowMenu(win.gadget)
+ EndIf
+ EndIf
+ EndIf
+ End Method
+
+ Rem
+ about: Is a menu item enabled.
+ EndRem
+ Method IsEnabled:Int(path:String)
+ Local ret:Int=False
+
+ If path<>"/"
+ Local node:TMenuItem=ResolvePath(path)
+
+ If node
+ ret=MenuEnabled(node.gadget)
+ EndIf
+ EndIf
+
+ Return ret
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is selected in the menu.
+ EndRem
+ Method OnMenuItem(path:String, tag:Object)
+ End Method
+
+ Rem
+ bbdoc: Popup the menu.
+ about: @win is a gadget to pass to MaxGUI. For some reason you need this, and the docs say it should be a window.
+ When I've tried any gadget would suffice, but don't come crying to me if it stops working for non-window gadgets.
+ EndRem
+ Method Popup(g:TMWidget)
+ PopupWindowMenu(g.gadget,root)
+ End Method
+
+ Method ToString:String()
+ Return "TMMenu:"+Super.ToString()
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed canvas.
+EndRem
+Type TMCanvas Extends TMWidget
+
+ Rem
+ bbdoc: Creates a managed canvas.
+ returns: The created canvas.
+ about: @x, @y, @w, @h, @group, @style and @gfxflags act the same as the MaxGUI arguments to @CreateCanvas(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMCanvas(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ OnRedrawEvent=New TMWEventListVoid
+ OnButtonDownEvent=New TMWEventListInt
+ OnButtonUpEvent=New TMWEventListInt
+ OnMouseMoveEvent=New TMWEventListIntInt
+ OnMouseWheelEvent=New TMWEventListInt
+ OnKeyDownEvent=New TMWEventListInt
+ OnKeyUpEvent=New TMWEventListInt
+ OnKeyEvent=New TMWEventListInt
+ BaseInitialise(CreateCanvas(x,y,w,h,group.gadget,style),group)
+ typename="TMCanvas"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Set the graphics so that the canvas can be drawn onto.
+ EndRem
+ Method SetupGraphics()
+ SetGraphics(CanvasGraphics(gadget))
+ End Method
+
+ Rem
+ bbdoc: Called when the canvas should be redrawn.
+ EndRem
+ Method OnRedraw()
+ End Method
+
+ Rem
+ bbdoc: Called when the canvas should be redrawn.
+ EndRem
+ Field OnRedrawEvent:TMWEventListVoid
+
+ Rem
+ bbdoc: Called when the a mouse button is pressed.
+ about: @button is the pressed button.
+ EndRem
+ Method OnButtonDown(button:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the a mouse button is pressed.
+ EndRem
+ Field OnButtonDownEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when the a mouse button is released.
+ about: @button is the released button.
+ EndRem
+ Method OnButtonUp(button:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the a mouse button is released.
+ EndRem
+ Field OnButtonUpEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when the mouse moves.
+ about: @x and @y are the mouse co-ordinates.
+ EndRem
+ Method OnMouseMove(x:Int, y:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is selected.
+ EndRem
+ Field OnMouseMoveEvent:TMWEventListIntInt
+
+ Rem
+ bbdoc: Called when the mouse wheel moves.
+ about: @delta is the amount the wheel moves.
+ EndRem
+ Method OnMouseWheel(delta:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the mouse wheel moves.
+ EndRem
+ Field OnMouseWheelEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when a key is held down.
+ about: @code is the key code.
+ EndRem
+ Method OnKeyDown(code:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when a key is held down.
+ EndRem
+ Field OnKeyDownEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when a key is released.
+ about: @code is the key code.
+ EndRem
+ Method OnKeyUp(code:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when a key is released.
+ EndRem
+ Field OnKeyUpEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when a key character is generated.
+ about: @code is the unicode value.
+ EndRem
+ Method OnKey(code:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when a key character is generated.
+ EndRem
+ Field OnKeyEvent:TMWEventListInt
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETPAINT
+ OnRedraw()
+ OnRedrawEvent.Fire(Self)
+ Case EVENT_MOUSEDOWN
+ OnButtonDown(e.data)
+ OnButtonDownEvent.Fire(Self,e.data)
+ Case EVENT_MOUSEUP
+ OnButtonUp(e.data)
+ OnButtonUpEvent.Fire(Self,e.data)
+ Case EVENT_MOUSEMOVE
+ OnMouseMove(e.x,e.y)
+ OnMouseMoveEvent.Fire(Self,e.x,e.y)
+ Case EVENT_MOUSEWHEEL
+ OnMouseWheel(e.data)
+ OnMouseWheelEvent.Fire(Self,e.data)
+ Case EVENT_KEYDOWN
+ OnKeyDown(e.data)
+ OnKeyDownEvent.Fire(Self,e.data)
+ Case EVENT_KEYUP
+ OnKeyUp(e.data)
+ OnKeyUpEvent.Fire(Self,e.data)
+ Case EVENT_KEYCHAR
+ OnKey(e.data)
+ OnKeyEvent.Fire(Self,e.data)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a toolbar.
+EndRem
+Type TMToolbar Extends TMWidget
+ Rem
+ bbdoc: Creates a managed toolbar.
+ returns: The created toolbar.
+ about: @source, @group and @style act the same as the MaxGUI arguments to @CreateToolBar(), except that @group is a TMWidget.
+ If @values is not NULL it is used to load up the initial options.
+ <b>IMPORTANT</b>: It is really not recommended to use COMBOBOX_EDITABLE as OnIndexChanged() is called when the user edits the field.
+ There seems to be no easy way to remedy this.
+ EndRem
+ Method Create:TMToolbar(source:Object, group:TMWidget, style:Int=0)
+ OnSelectedEvent=New TMWEventListInt
+ BaseInitialise(CreateToolBar(source,0,0,0,0,group.gadget,style),group)
+ typename="TMToolbar"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Adds an item to the toolbar.
+ EndRem
+ Method AddItem(icon:Int, flags:Int=0, tooltip:String=Null)
+ AddGadgetItem(gadget,"",flags,icon,tooltip,Null)
+ End Method
+
+ Rem
+ bbdoc: Set the tooltips.
+ EndRem
+ Method SetTooltips(tips:String[])
+ SetToolBarTips(gadget,tips)
+ End Method
+
+ Rem
+ bbdoc: Enable or disable a particular item.
+ EndRem
+ Method ItemEnabled(index:Int, state:Int)
+ If state
+ EnableGadgetItem(gadget,index)
+ Else
+ DisableGadgetItem(gadget,index)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Called when an icon is selected.
+ about: @index is the selected index.
+ EndRem
+ Method OnSelected(index:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when an icon is selected.
+ EndRem
+ Field OnSelectedEvent:TMWEventListInt
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_GADGETACTION
+ OnSelected(e.data)
+ OnSelectedEvent.Fire(Self,e.data)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed panel.
+EndRem
+Type TMPanel Extends TMWidget
+
+ Rem
+ bbdoc: Creates a managed panel.
+ returns: The created panel.
+ about: @x, @y, @w, @h, @group, @style and @title act the same as the MaxGUI arguments to @CreatePanel(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMPanel(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0, title:String="")
+ OnButtonDownEvent=New TMWEventListInt
+ OnButtonUpEvent=New TMWEventListInt
+ OnMouseMoveEvent=New TMWEventListIntInt
+ OnMouseWheelEvent=New TMWEventListInt
+ OnKeyDownEvent=New TMWEventListInt
+ OnKeyUpEvent=New TMWEventListInt
+ OnKeyEvent=New TMWEventListInt
+ BaseInitialise(CreatePanel(x,y,w,h,group.gadget,style,title),group)
+ typename="TMPanel"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Called when the a mouse button is pressed.
+ about: @button is the pressed button.
+ EndRem
+ Method OnButtonDown(button:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the a mouse button is pressed.
+ EndRem
+ Field OnButtonDownEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when the a mouse button is released.
+ about: @button is the released button.
+ EndRem
+ Method OnButtonUp(button:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the a mouse button is released.
+ EndRem
+ Field OnButtonUpEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when the mouse moves.
+ about: @x and @y are the mouse co-ordinates.
+ EndRem
+ Method OnMouseMove(x:Int, y:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the an item is selected.
+ EndRem
+ Field OnMouseMoveEvent:TMWEventListIntInt
+
+ Rem
+ bbdoc: Called when the mouse wheel moves.
+ about: @delta is the amount the wheel moves.
+ EndRem
+ Method OnMouseWheel(delta:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when the mouse wheel moves.
+ EndRem
+ Field OnMouseWheelEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when a key is held down.
+ about: @code is the key code.
+ EndRem
+ Method OnKeyDown(code:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when a key is held down.
+ EndRem
+ Field OnKeyDownEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when a key is released.
+ about: @code is the key code.
+ EndRem
+ Method OnKeyUp(code:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when a key is released.
+ EndRem
+ Field OnKeyUpEvent:TMWEventListInt
+
+ Rem
+ bbdoc: Called when a key character is generated.
+ about: @code is the unicode value.
+ EndRem
+ Method OnKey(code:Int)
+ End Method
+
+ Rem
+ bbdoc: Called when a key character is generated.
+ EndRem
+ Field OnKeyEvent:TMWEventListInt
+
+ Method Handle(e:TEvent)
+ Select e.id
+ Case EVENT_MOUSEDOWN
+ OnButtonDown(e.data)
+ OnButtonDownEvent.Fire(Self,e.data)
+ Case EVENT_MOUSEUP
+ OnButtonUp(e.data)
+ OnButtonUpEvent.Fire(Self,e.data)
+ Case EVENT_MOUSEMOVE
+ OnMouseMove(e.x,e.y)
+ OnMouseMoveEvent.Fire(Self,e.x,e.y)
+ Case EVENT_MOUSEWHEEL
+ OnMouseWheel(e.data)
+ OnMouseWheelEvent.Fire(Self,e.data)
+ Case EVENT_KEYDOWN
+ OnKeyDown(e.data)
+ OnKeyDownEvent.Fire(Self,e.data)
+ Case EVENT_KEYUP
+ OnKeyUp(e.data)
+ OnKeyUpEvent.Fire(Self,e.data)
+ Case EVENT_KEYCHAR
+ OnKey(e.data)
+ OnKeyEvent.Fire(Self,e.data)
+ Default
+ Super.Handle(e)
+ End Select
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a managed progress bar.
+EndRem
+Type TMProgressBar Extends TMWidget
+
+ Rem
+ bbdoc: Creates a managed progress bar.
+ returns: The created progress bar.
+ about: @x, @y, @w, @h, @group and @style act the same as the MaxGUI arguments to @CreateProgBar(), except that @group is a TMWidget.
+ EndRem
+ Method Create:TMProgressBar(x:Int, y:Int, w:Int, h:Int, group:TMWidget, style:Int=0)
+ BaseInitialise(CreateProgBar(x,y,w,h,group.gadget,style),group)
+ typename="TMProgressBar"
+ Return Self
+ End Method
+
+ Rem
+ bbdoc: Set the value for the progress bar.
+ about: @value is the value (between 0 and 1).
+ EndRem
+ Method SetValue(value:Double)
+ UpdateProgBar(gadget,value)
+ End Method
+End Type
+
+
+Rem
+bbdoc: Enters the event processing loop.
+about: @top is the top level TMWindow For the application. The loop continues Until the @closed Field of this window is TRUE.
+Your code can do it's own event loop if required -- all this function does is continually call WaitEvent and is simply provided as
+a basic main loop.
+EndRem
+Function MWidgetMainLoop(top:TMWindow)
+ While Not top.closed
+ WaitEvent()
+ Wend
+End Function
+
+
+Private
+
+Function FixedExtractDir:String(p:String)
+ p=ExtractDir(p)
+ If p.length=0
+ p="/"
+ EndIf
+ Return p
+End Function
+
+Type Static
+ Global list:TList
+ Global menu:TList
+ Global menuid:Int
+
+ Function Init()
+ list=CreateList()
+ menu=CreateList()
+ menuid=0
+ AddHook(EmitEventHook,EventHandler)
+ End Function
+
+ Function EventHandler:Object(id:Int, data:Object, context:Object)
+ Local e:TEvent=TEvent(data)
+
+ DebugLog "Got event : " + e.ToString()
+
+ If e
+ If e.id=EVENT_MENUACTION
+ For Local m:TMenuItem=EachIn menu
+ If m.id=e.data
+ DebugLog "Passing menu event to " + m.owner.ToString()
+ m.owner.OnMenuItem(m.path,m.tag)
+ If m.callback
+ m.callback(m.owner,m.path,m.tag)
+ EndIf
+ EndIf
+ Next
+ Else
+ For Local g:TMWidget=EachIn list
+ If g And g.gadget And g.gadget=e.source
+ DebugLog "Passing event to " + g.ToString()
+ g.Handle(e)
+ EndIf
+ Next
+ EndIf
+ EndIf
+
+ Return e
+ End Function
+
+ Function Register(w:TMWidget)
+ list.AddLast(w)
+ w.OnManage()
+ w.OnManageEvent.Fire(w)
+ End Function
+
+ Function Deregister(w:TMWidget)
+ w.OnUnmanage()
+ w.OnUnmanageEvent.Fire(w)
+ list.Remove(w)
+ End Function
+
+ Function RegisterMenuItem(m:TMenuItem)
+ menu.AddLast(m)
+ End Function
+
+ Function DeregisterMenuItem(m:TMenuItem)
+ menu.Remove(m)
+ End Function
+
+ Function NextMenuID:Int()
+ menuid:+1
+ Return menuid
+ End Function
+End Type
+
+Static.Init()
diff --git a/showlicense.mod/showlicense.bmx b/showlicense.mod/showlicense.bmx
index 09ea7c3..06651d2 100644
--- a/showlicense.mod/showlicense.bmx
+++ b/showlicense.mod/showlicense.bmx
@@ -1,200 +1,199 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.showlicense
-EndRem
-Module noddybox.showlicense
-
-ModuleInfo "Framework: License acceptance routines"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-Import brl.max2d
-Import brl.stream
-Import brl.basic
-Import brl.linkedlist
-
-Rem
-bbdoc: Displays a license for the user to accept.
-returns: True if the license is accepted, false otherwise.
-about: The license stored in text format at the URL @short_license is displayed with a title of @title.
-If the URL @full_license is not null then the user is provided with an option to display that too.
-The width of text in the license files must fit on the screen...
-EndRem
-Function ShowLicense:Int(title:String, short_license:String, full_license:String)
- Local accepted:Int=False
- Local license:TLicense=New TLicense
-
- If full_license
- license.Init(title,short_license,["ACCEPT","DECLINE","VIEW FULL LICENSE"])
- Else
- license.Init(title,short_license,["ACCEPT","DECLINE"])
- EndIf
-
- Select license.Show()
- Case 0
- accepted=True
- Case 1
- Case 2
- license=New TLicense
- license.Init(title,full_license,["ACCEPT","DECLINE"])
- If (license.Show()=0)
- accepted=True
- End If
- End Select
-
- Return accepted
-End Function
-
-Private
-
-Type TLicense
- Field top:Int
- Field bottom:Int
- Field list:TList
- Field item:TLink
- Field title:String
- Field opts:String[]
- Field sel:Int
- Field col:Int
- Field coli:Int
-
- Method New()
- End Method
-
- Method Centre(s:String, y:Int)
- DrawText(s,(GraphicsWidth()-TextWidth(s))/2,y)
- End Method
-
- Method MaxHeight:Int()
- Return TextHeight("X")
- End Method
-
- Method Init(t:String, u:String, o:String[])
- Local str:TStream=ReadStream(u)
-
- Assert str,"Unable to open help file"
-
- list=CreateList()
-
- While Not str.Eof()
- list.AddLast(str.ReadLine())
- Wend
-
- str.Close()
-
- title=t
- item=list.FirstLink()
-
- top=MaxHeight()*2
- bottom=GraphicsHeight()-MaxHeight()*3
- opts=o
- sel=0
- col=255
- coli=-5
- End Method
-
- Method Draw()
- Local y:Int=top+1
- Local i:TLink=item
-
- While y<bottom And i
- Local s:String=String(i.Value())
- DrawText(s,0,y)
- y:+TextHeight(s)
- i=i.NextLink()
- Wend
-
- SetColor(0,0,0)
- DrawRect(0,0,GraphicsWidth(),top)
- DrawRect(0,bottom,GraphicsWidth(),GraphicsHeight()-bottom)
-
- SetColor(255,255,255)
- DrawLine(0,TOP,GraphicsWidth(),TOP)
- DrawLine(0,BOTTOM,GraphicsWidth(),BOTTOM)
-
- Centre(title,MaxHeight()/2)
- Centre("CURSORS VIEW AND CHOOSE. RETURN SELECTS.",bottom+MaxHeight()/2)
-
- Local x:Int=0
- y=GraphicsHeight()-MaxHeight()
-
- For Local f:Int=0 Until opts.length
- If f=sel
- SetColor(col/2,col/2,128+col)
- DrawRect(x,y,TextWidth(opts[f]),MaxHeight())
- SetColor(255,255,255)
- EndIf
- DrawText(opts[f],x,y)
- x:+TextWidth(opts[f])+20
- Next
-
- col:+coli
-
- If col<128 Or col>255
- coli=-coli
- col:+coli
- EndIf
- End Method
-
- Method Current:String()
- Return String(item.Value())
- End Method
-
- Method Show:Int()
- Local done:Int=False
-
- FlushKeys()
-
- While Not done
- Cls
-
- Draw()
-
- If KeyDown(KEY_DOWN)
- If item.NextLink()
- item=item.NextLink()
- EndIf
- ElseIf KeyDown(KEY_UP)
- If item.PrevLink()
- item=item.PrevLink()
- EndIf
- ElseIf KeyHit(KEY_LEFT)
- sel=Max(0,sel-1)
- ElseIf KeyHit(KEY_RIGHT)
- sel=Min(opts.length-1,sel+1)
- ElseIf KeyHit(KEY_RETURN)
- done=True
- EndIf
-
- Flip
- Wend
-
- FlushKeys()
-
- Return sel
- End Method
-End Type
-
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.showlicense
+EndRem
+Module noddybox.showlicense
+
+ModuleInfo "Framework: License acceptance routines"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.max2d
+Import brl.stream
+Import brl.basic
+Import brl.linkedlist
+
+Rem
+bbdoc: Displays a license for the user to accept.
+returns: True if the license is accepted, false otherwise.
+about: The license stored in text format at the URL @short_license is displayed with a title of @title.
+If the URL @full_license is not null then the user is provided with an option to display that too.
+The width of text in the license files must fit on the screen...
+EndRem
+Function ShowLicense:Int(title:String, short_license:String, full_license:String)
+ Local accepted:Int=False
+ Local license:TLicense=New TLicense
+
+ If full_license
+ license.Init(title,short_license,["ACCEPT","DECLINE","VIEW FULL LICENSE"])
+ Else
+ license.Init(title,short_license,["ACCEPT","DECLINE"])
+ EndIf
+
+ Select license.Show()
+ Case 0
+ accepted=True
+ Case 1
+ Case 2
+ license=New TLicense
+ license.Init(title,full_license,["ACCEPT","DECLINE"])
+ If (license.Show()=0)
+ accepted=True
+ End If
+ End Select
+
+ Return accepted
+End Function
+
+Private
+
+Type TLicense
+ Field top:Int
+ Field bottom:Int
+ Field list:TList
+ Field item:TLink
+ Field title:String
+ Field opts:String[]
+ Field sel:Int
+ Field col:Int
+ Field coli:Int
+
+ Method New()
+ End Method
+
+ Method Centre(s:String, y:Int)
+ DrawText(s,(GraphicsWidth()-TextWidth(s))/2,y)
+ End Method
+
+ Method MaxHeight:Int()
+ Return TextHeight("X")
+ End Method
+
+ Method Init(t:String, u:String, o:String[])
+ Local str:TStream=ReadStream(u)
+
+ Assert str,"Unable to open help file"
+
+ list=CreateList()
+
+ While Not str.Eof()
+ list.AddLast(str.ReadLine())
+ Wend
+
+ str.Close()
+
+ title=t
+ item=list.FirstLink()
+
+ top=MaxHeight()*2
+ bottom=GraphicsHeight()-MaxHeight()*3
+ opts=o
+ sel=0
+ col=255
+ coli=-5
+ End Method
+
+ Method Draw()
+ Local y:Int=top+1
+ Local i:TLink=item
+
+ While y<bottom And i
+ Local s:String=String(i.Value())
+ DrawText(s,0,y)
+ y:+TextHeight(s)
+ i=i.NextLink()
+ Wend
+
+ SetColor(0,0,0)
+ DrawRect(0,0,GraphicsWidth(),top)
+ DrawRect(0,bottom,GraphicsWidth(),GraphicsHeight()-bottom)
+
+ SetColor(255,255,255)
+ DrawLine(0,TOP,GraphicsWidth(),TOP)
+ DrawLine(0,BOTTOM,GraphicsWidth(),BOTTOM)
+
+ Centre(title,MaxHeight()/2)
+ Centre("CURSORS VIEW AND CHOOSE. RETURN SELECTS.",bottom+MaxHeight()/2)
+
+ Local x:Int=0
+ y=GraphicsHeight()-MaxHeight()
+
+ For Local f:Int=0 Until opts.length
+ If f=sel
+ SetColor(col/2,col/2,128+col)
+ DrawRect(x,y,TextWidth(opts[f]),MaxHeight())
+ SetColor(255,255,255)
+ EndIf
+ DrawText(opts[f],x,y)
+ x:+TextWidth(opts[f])+20
+ Next
+
+ col:+coli
+
+ If col<128 Or col>255
+ coli=-coli
+ col:+coli
+ EndIf
+ End Method
+
+ Method Current:String()
+ Return String(item.Value())
+ End Method
+
+ Method Show:Int()
+ Local done:Int=False
+
+ FlushKeys()
+
+ While Not done
+ Cls
+
+ Draw()
+
+ If KeyDown(KEY_DOWN)
+ If item.NextLink()
+ item=item.NextLink()
+ EndIf
+ ElseIf KeyDown(KEY_UP)
+ If item.PrevLink()
+ item=item.PrevLink()
+ EndIf
+ ElseIf KeyHit(KEY_LEFT)
+ sel=Max(0,sel-1)
+ ElseIf KeyHit(KEY_RIGHT)
+ sel=Min(opts.length-1,sel+1)
+ ElseIf KeyHit(KEY_RETURN)
+ done=True
+ EndIf
+
+ Flip
+ Wend
+
+ FlushKeys()
+
+ Return sel
+ End Method
+End Type
+
diff --git a/simplegui.mod/simplegui.bmx b/simplegui.mod/simplegui.bmx
index fcf0c17..c1ffc64 100644
--- a/simplegui.mod/simplegui.bmx
+++ b/simplegui.mod/simplegui.bmx
@@ -30,7 +30,6 @@ ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
ModuleInfo "Author: Ian Cowburn"
ModuleInfo "Version: $Revision$"
-Strict
Import brl.max2d
Import brl.filesystem
Import brl.basic
diff --git a/vector.mod/vector.bmx b/vector.mod/vector.bmx
index 2b2bb55..e20aaaa 100644
--- a/vector.mod/vector.bmx
+++ b/vector.mod/vector.bmx
@@ -1,199 +1,198 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.vector
-EndRem
-Module noddybox.vector
-
-ModuleInfo "Framework: Simple Vector class"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-Import brl.math
-
-Rem
-bbdoc: Implements a 3D vector. Can be used as a 2D vector by ignoring Z.
-EndRem
-Type TVector
-
- Rem
- bbdoc: The X component of the vector.
- EndRem
- Field x:Double
- Rem
- bbdoc: The Y component of the vector.
- EndRem
- Field y:Double
- Rem
- bbdoc: The Z component of the vector.
- EndRem
- Field z:Double
-
-
- Rem
- bbdoc: Create a vector.
- returns: The created vector.
- about: @dx, @dy and @dz are the initial component values.
- EndRem
- Function Create:TVector(dx:Double=0.0, dy:Double=0.0, dz:Double=0.0)
- Local o:TVector
-
- o=New TVector
-
- o.x=dx
- o.y=dy
- o.z=dz
-
- Return o
- End Function
-
- Rem
- bbdoc: Clone this vector to a new object.
- returns: The created vector.
- EndRem
- Method Clone:TVector()
- Return Create(x,y,z)
- End Method
-
- Rem
- bbdoc: Is the vector null.
- returns: True if the vector is null (all components zero), False otherwise.
- EndRem
- Method IsNull:Int()
- Return x=0 And y=0 And z=0
- End Method
-
- Rem
- bbdoc: The length of the vector.
- returns: The length of the vector.
- EndRem
- Method Length:Double()
- If (IsNull())
- Return 0
- Else
- Return Sqr(x*x+y*y+z*z)
- EndIf
- End Method
-
- Rem
- bbdoc: Normalise the vector so its length is 1.
- EndRem
- Method Normalise()
- Local l:Double=Length()
- If (l<>0)
- x:/l
- y:/l
- z:/l
- EndIf
- End Method
-
- Rem
- bbdoc: Set the vector so its length is @sc.
- EndRem
- Method SetLength(sc:Double)
- Normalise()
- Scale(sc)
- End Method
-
- Rem
- bbdoc: Adds @sc to all components.
- EndRem
- Method AddScalar(sc:Double)
- x:+sc
- y:+sc
- z:+sc
- End Method
-
- Rem
- bbdoc: Reverse the direction of the vector.
- EndRem
- Method Minus()
- x=-x
- y=-y
- z=-z
- End Method
-
- Rem
- bbdoc: Scale all components by @sc.
- EndRem
- Method Scale(sc:Double)
- x:*sc
- y:*sc
- z:*sc
- End Method
-
- Rem
- bbdoc: Add another vector to this vector.
- EndRem
- Method Add(v:TVector)
- x:+v.x
- y:+v.y
- z:+v.z
- End Method
-
- Rem
- bbdoc: Subtract another vector from this vector.
- EndRem
- Method Subtract(v:TVector)
- x:-v.x
- y:-v.y
- z:-v.z
- End Method
-
- Rem
- bbdoc: Scale this vector by another vector.
- EndRem
- Method ScaleVector(v:TVector)
- x:*v.x
- y:*v.y
- z:*v.z
- End Method
-
- Rem
- bbdoc: Inverse scale this vector by another vector.
- EndRem
- Method InverseScaleVector(v:TVector)
- x:/v.x
- y:/v.y
- z:/v.z
- End Method
-
- Rem
- bbdoc: Calculate the cross product of this vector with another.
- returns: A new @TVector holding the cross product.
- EndRem
- Method Cross:TVector(v:TVector)
- Return TVector.Create(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y)
- End Method
-
- Rem
- bbdoc: Calculate the dot product of this vector with another.
- returns: The dot product.
- EndRem
- Method Dot:Double(v:TVector)
- Return x*v.x + y*v.y + z*v.z
- End Method
-
-End Type
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.vector
+EndRem
+Module noddybox.vector
+
+ModuleInfo "Framework: Simple Vector class"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.math
+
+Rem
+bbdoc: Implements a 3D vector. Can be used as a 2D vector by ignoring Z.
+EndRem
+Type TVector
+
+ Rem
+ bbdoc: The X component of the vector.
+ EndRem
+ Field x:Double
+ Rem
+ bbdoc: The Y component of the vector.
+ EndRem
+ Field y:Double
+ Rem
+ bbdoc: The Z component of the vector.
+ EndRem
+ Field z:Double
+
+
+ Rem
+ bbdoc: Create a vector.
+ returns: The created vector.
+ about: @dx, @dy and @dz are the initial component values.
+ EndRem
+ Function Create:TVector(dx:Double=0.0, dy:Double=0.0, dz:Double=0.0)
+ Local o:TVector
+
+ o=New TVector
+
+ o.x=dx
+ o.y=dy
+ o.z=dz
+
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Clone this vector to a new object.
+ returns: The created vector.
+ EndRem
+ Method Clone:TVector()
+ Return Create(x,y,z)
+ End Method
+
+ Rem
+ bbdoc: Is the vector null.
+ returns: True if the vector is null (all components zero), False otherwise.
+ EndRem
+ Method IsNull:Int()
+ Return x=0 And y=0 And z=0
+ End Method
+
+ Rem
+ bbdoc: The length of the vector.
+ returns: The length of the vector.
+ EndRem
+ Method Length:Double()
+ If (IsNull())
+ Return 0
+ Else
+ Return Sqr(x*x+y*y+z*z)
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Normalise the vector so its length is 1.
+ EndRem
+ Method Normalise()
+ Local l:Double=Length()
+ If (l<>0)
+ x:/l
+ y:/l
+ z:/l
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Set the vector so its length is @sc.
+ EndRem
+ Method SetLength(sc:Double)
+ Normalise()
+ Scale(sc)
+ End Method
+
+ Rem
+ bbdoc: Adds @sc to all components.
+ EndRem
+ Method AddScalar(sc:Double)
+ x:+sc
+ y:+sc
+ z:+sc
+ End Method
+
+ Rem
+ bbdoc: Reverse the direction of the vector.
+ EndRem
+ Method Minus()
+ x=-x
+ y=-y
+ z=-z
+ End Method
+
+ Rem
+ bbdoc: Scale all components by @sc.
+ EndRem
+ Method Scale(sc:Double)
+ x:*sc
+ y:*sc
+ z:*sc
+ End Method
+
+ Rem
+ bbdoc: Add another vector to this vector.
+ EndRem
+ Method Add(v:TVector)
+ x:+v.x
+ y:+v.y
+ z:+v.z
+ End Method
+
+ Rem
+ bbdoc: Subtract another vector from this vector.
+ EndRem
+ Method Subtract(v:TVector)
+ x:-v.x
+ y:-v.y
+ z:-v.z
+ End Method
+
+ Rem
+ bbdoc: Scale this vector by another vector.
+ EndRem
+ Method ScaleVector(v:TVector)
+ x:*v.x
+ y:*v.y
+ z:*v.z
+ End Method
+
+ Rem
+ bbdoc: Inverse scale this vector by another vector.
+ EndRem
+ Method InverseScaleVector(v:TVector)
+ x:/v.x
+ y:/v.y
+ z:/v.z
+ End Method
+
+ Rem
+ bbdoc: Calculate the cross product of this vector with another.
+ returns: A new @TVector holding the cross product.
+ EndRem
+ Method Cross:TVector(v:TVector)
+ Return TVector.Create(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y)
+ End Method
+
+ Rem
+ bbdoc: Calculate the dot product of this vector with another.
+ returns: The dot product.
+ EndRem
+ Method Dot:Double(v:TVector)
+ Return x*v.x + y*v.y + z*v.z
+ End Method
+
+End Type
diff --git a/vectorgfx.mod/vectorgfx.bmx b/vectorgfx.mod/vectorgfx.bmx
index 06018a8..a44635f 100644
--- a/vectorgfx.mod/vectorgfx.bmx
+++ b/vectorgfx.mod/vectorgfx.bmx
@@ -1,683 +1,682 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.vectorgfx
-EndRem
-Module noddybox.vectorgfx
-
-ModuleInfo "Framework: 2D Vector Graphics classes"
-ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-Import brl.linkedlist
-Import brl.math
-Import brl.endianstream
-Import brl.max2d
-Import noddybox.vector
-Import noddybox.algorithm
-
-Rem
-bbdoc: Wibble
-about: Wobble
-EndRem
-
-Rem
-bbdoc: Defines a method for drawing vector lines
-about: For an example of creating a line drawing routine view the LineSolid type in the private section of this module.
-EndRem
-Type TVectorGfxLineStyle Abstract
- Rem
- bbdoc: Draws a vector line using IDs and @TVectorGfxCollisionMap method.
- returns: The or'ed mask of all collision IDs overwritten in @colmap by this line, or zero if @colmap is null.
- about: This routine must draw a line from @x1, @y1 to @x2, @y2 using the colour @r,@g,@b.
- about: @id, @obj and @line must be written into the collision map @colmap if @colmap is not null and @actor is false.
- about: If @colmap is set and @actor true, then collisions must be returned but no points written into the collision map.
- about: If @colmap is set, @actor is true and @list is not null then any collisions should be recorded into this list
- about: (no requirement for duplicate checking).
- EndRem
- Method LineToCollisionMap:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList) Abstract
-
- Rem
- bbdoc: Draws a vector line using the point list method.
- about: This routine must draw a line from @x1, @y1 to @x2, @y2 using the colour @r,@g,@b.
- about: If list is not null, then the points drawn must be stored in the list as @TVectorGfxPoint objects.
- about: For an example of creating a line drawing routine view the LineSolid type in the private section of this module.
- EndRem
- Method LineToPointList:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, list:TList) Abstract
-End Type
-
-Rem
-bbdoc: Set to use solid lines for drawing.
-about: This mode draws vector lines as solid colour lines using the current alpha, and is the default mode.
-EndRem
-Function VectorGfxSetSolid()
- Static.linedraw=New LineSolid
-End Function
-
-Rem
-bbdoc: Set to use a custom drawing method.
-EndRem
-Function VectorGfxSetCustom(linedraw:TVectorGfxLineStyle)
- Static.linedraw=linedraw
-End Function
-
-Rem
-bbdoc: Defines a point in the vector graphics collision map.
-EndRem
-Type TVectorGfxCollision
- Rem
- bbdoc: The X co-ordinate of this collision (in the object co-ordinate space).
- EndRem
- Field x:Int
-
- Rem
- bbdoc: The Y co-ordinate of this collision (in the object co-ordinate space).
- EndRem
- Field y:Int
-
- Rem
- bbdoc: The collision masks at this point.
- EndRem
- Field mask:Int
-
- Rem
- bbdoc: The last vector object that wrote at this point.
- EndRem
- Field obj:TVectorGfxObject
-
- Rem
- bbdoc: The index of the line in the last vector object that wrote at this point.
- EndRem
- Field line:Int
-
- Function Create:TVectorGfxCollision(x:Int, y:Int, mask:Int, obj:TVectorGfxObject, line:Int)
- Local o:TVectorGfxCollision=New TVectorGfxCollision
- o.x=x
- o.y=y
- o.mask=mask
- o.obj=obj
- o.line=line
- Return o
- End Function
-End Type
-
-
-Rem
-bbdoc: Defines a vector graphics collision map.
-about: Collisions using this method in the library are defined using a bitmask (allowing 32 collision masks).
-EndRem
-Type TVectorGfxCollisionMap
-
- Field width:Int
- Field height:Int
- Field xoff:Int
- Field yoff:Int
- Field data:TVectorGfxCollision[,]
-
- Rem
- bbdoc: Create a collision map.
- returns: The created collision map.
- about: @width and @height are the size of the collision map.
- EndRem
- Function Create:TVectorGfxCollisionMap(width:Int, height:Int)
- Local o:TVectorGfxCollisionMap=New TVectorGfxCollisionMap
-
- o.width=width
- o.height=height
- o.xoff=0
- o.yoff=0
- o.Clear()
- Return o
- End Function
-
- Rem
- bbdoc: Set the offset of the collision map.
- about: @x and @y are the offsets into the co-ordinate space where the collision map lives.
- EndRem
- Method SetOffset(x:Int, y:Int)
- xoff=x
- yoff=y
- End Method
-
- Rem
- bbdoc: Get a collision point.
- returns: The collision point, or null if nothing drawn there.
- about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space)
- EndRem
- Method GetCollision:TVectorGfxCollision(x:Int, y:Int)
- If x<xoff Or x>=xoff+width Or y<yoff Or y>=yoff+height
- Return Null
- Else
- Return data[x-xoff,y-yoff]
- EndIf
- End Method
-
- Rem
- bbdoc: Set a collision point.
- returns: The current collision mask for that point, or zero if the point is out of the map's range.
- about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space)
- EndRem
- Method SetCollision:Int(x:Int, y:Int, id:Int, obj:TVectorGfxObject, line:Int)
- If x<xoff Or x>=xoff+width Or y<yoff Or y>=yoff+height
- Return 0
- EndIf
-
- Local ax:Int=x-xoff
- Local ay:Int=y-yoff
-
- Local cur:TVectorGfxCollision=data[ax,ay]
-
- If Not cur
- cur=TVectorGfxCollision.Create(x,y,id,obj,line)
- data[ax,ay]=cur
- Else
- cur.mask:|id
- cur.obj=obj
- cur.line=line
- EndIf
-
- Return cur.mask
- End Method
-
- Rem
- bbdoc: Clear the collision map
- EndRem
- Method Clear()
- data=New TVectorGfxCollision[width,height]
- End Method
-End Type
-
-
-Rem
-bbdoc: Defines a 2D vector graphics object
-EndRem
-Type TVectorGfxObject
- Rem
- bbdoc: The points making up this object
- EndRem
- Field points:TVectorGfxPoint[]
- Rem
- bbdoc: The lines making up this object
- EndRem
- Field lines:TVectorGfxLine[]
- Rem
- bbdoc: The X co-ordinate of the object
- EndRem
- Field x:Int
- Rem
- bbdoc: The Y co-ordinate of the object
- EndRem
- Field y:Int
- Rem
- bbdoc: The minimum X co-ordinate of the object. Only valid after a call to SetPoints().
- EndRem
- Field min_x:Int
- Rem
- bbdoc: The maximum X co-ordinate of the object. Only valid after a call to SetPoints().
- EndRem
- Field max_x:Int
- Rem
- bbdoc: The minimum Y co-ordinate of the object. Only valid after a call to SetPoints().
- EndRem
- Field min_y:Int
- Rem
- bbdoc: The maximum Y co-ordinate of the object. Only valid after a call to SetPoints().
- EndRem
- Field max_y:Int
- Rem
- bbdoc: The width of the object. Only valid after a call to SetPoints().
- EndRem
- Field width:Int
- Rem
- bbdoc: The height of the object. Only valid after a call to SetPoints().
- EndRem
- Field height:Int
- Rem
- bbdoc: The angle of the object, as degrees*10. Must be within the range 0-3599 inclusive.
- EndRem
- Field ang:Int
- Rem
- bbdoc: The scale of the object.
- EndRem
- Field scale:Double
-
- Field rotated:TVectorGfxPoint[]
-
- Rem
- bbdoc: Creates a new empty object
- returns: The created object.
- EndRem
- Method New()
- points=Null
- lines=Null
- rotated=Null
- x=0
- y=0
- min_x=9999999
- min_y=9999999
- max_x=-9999999
- max_y=-9999999
- width=0
- height=0
- ang=0
- scale=1
- End Method
-
- Rem
- bbdoc: Clones this object
- about: Returns a copy of this object, with its own copy of the line and points.
- EndRem
- Method Clone:TVectorGfxObject()
- Local o:TVectorGfxObject=New TVectorGfxObject
- o.x=x
- o.y=y
- o.min_x=min_x
- o.min_y=min_y
- o.max_x=max_x
- o.max_y=max_y
- o.width=width
- o.height=height
- o.ang=ang
- o.scale=scale
- o.SetPoints(points)
- o.SetLines(lines)
- Return o
- End Method
-
- Rem
- bbdoc: Sets the points for this object
- about: @pa is an array of points for this object.
- EndRem
- Method SetPoints(pa:Object[])
- points=New TVectorGfxPoint[pa.length]
- For Local f:Int=0 Until pa.length
- points[f]=TVectorGfxPoint(pa[f])
- min_x=Min(min_x,points[f].x)
- min_y=Min(min_y,points[f].y)
- max_x=Max(max_x,points[f].x)
- max_y=Max(max_y,points[f].y)
- Next
- width=max_x-min_x
- height=max_y-min_y
- End Method
-
- Rem
- bbdoc: Sets the lines for this object.
- about: @la is the array of lines for this object.
- EndRem
- Method SetLines(la:Object[])
- lines=New TVectorGfxLine[la.length]
- For Local f:Int=0 Until la.length
- lines[f]=TVectorGfxLine(la[f])
- Next
- End Method
-
- Rem
- bbdoc: Whether a point is inside the object
- returns: True if the point lies inside the object. The object is assumed to be a closed polygon for this test.
- about: @cx, @cy is the point to test.
- about: This routine is based on code from comp.graphics.algorithms FAQ 2.03
- EndRem
- Method IsInside:Int(cx:Int, cy:Int)
- If rotated=Null
- Return False
- EndIf
-
- Local cross:Int=False
-
- For Local l:TVectorGfxLine=EachIn lines
- Local x1:Int=x+rotated[l.i1].x
- Local y1:Int=y+rotated[l.i1].y
- Local x2:Int=x+rotated[l.i2].x
- Local y2:Int=y+rotated[l.i2].y
-
- If ((((y1<=cy) And (cy<y2)) Or ((y2<=cy) And (cy<y1))) And (cx < (x2 - x1) * (cy - y1) / (y2 - y1) + x1))
- cross=Not cross
- EndIf
- Next
-
- Return cross
- End Method
-
- Rem
- bbdoc: A line's adjusted co-ordinates.
- returns: The rotated and scaled points (in object co-ordinates) of the line.
- about: @i is the index of the line to return the points for.
- about: Calling it before drawing the object will return null.
- EndRem
- Method AdjustedCoords:TVectorGfxPoint[](i:Int)
- If rotated=Null
- Return Null
- EndIf
-
- Local p:TVectorGfxPoint[]=New TVectorGfxPoint[2]
- Local l:TVectorGfxLine=lines[i]
- p[0]=rotated[l.i1]
- p[1]=rotated[l.i2]
- Return p
- End Method
-
- Rem
- bbdoc: A line's normal.
- returns: The normal of the selected line.
- about: @i is the index of the line to return the normal of. This will return the normal due to the rotation of the object after the object is drawn.
- about: Calling it before drawing the object will return null.
- EndRem
- Method Normal:TVector(i:Int)
- If rotated=Null
- Return Null
- EndIf
-
- Local l:TVectorGfxLine=lines[i]
- Local v:TVector=TVector.Create(rotated[l.i2].y-rotated[l.i1].y,rotated[l.i1].x-rotated[l.i2].x)
- v.Normalise()
- Return v
- End Method
-
- Rem
- bbdoc: Loads the object from the supplied @filename.
- returns: The loaded object, or null if the file could not be opened.
- EndRem
- Function Load:TVectorGfxObject(filename:String)
- Local s:TStream=ReadStream(filename)
-
- If Not s
- Return Null
- EndIf
-
- s=LittleEndianStream(s)
- Local o:TVectorGfxObject=New TVectorGfxObject
-
- o.x=s.ReadInt()
- o.y=s.ReadInt()
- o.ang=s.ReadInt()
-
- Local l:TList=CreateList()
- Local i:Int=s.ReadInt()
-
- For Local f=0 Until i
- l.AddLast(TVectorGfxPoint.Load(s))
- Next
-
- o.SetPoints(l.ToArray())
-
- l.Clear()
-
- i=s.ReadInt()
-
- For Local f=0 Until i
- l.AddLast(TVectorGfxLine.Load(s))
- Next
-
- o.SetLines(l.ToArray())
-
- s.Close()
-
- Return o
- End Function
-
- Rem
- bbdoc: Saves the object to the supplied @filename.
- EndRem
- Method Save(filename:String)
- Local s:TStream=WriteStream(filename)
-
- If Not s
- Return Null
- EndIf
-
- s=LittleEndianStream(s)
-
- s.WriteInt(x)
- s.WriteInt(y)
- s.WriteInt(ang)
-
- s.WriteInt(points.length)
- For Local p:TVectorGfxPoint=EachIn points
- p.Save(s)
- Next
-
- s.WriteInt(lines.length)
- For Local l:TVectorGfxLine=EachIn lines
- l.Save(s)
- Next
-
- s.Close()
- End Method
-
- Rem
- bbdoc: Draw the object, not bothering about collisions.
- EndRem
- Method Draw()
- rotated=New TVectorGfxPoint[points.length]
-
- For Local f:Int=0 Until points.length
- Local p:TAlgoPointD=DoRotateD(points[f].x*scale,points[f].y*scale,ang)
- rotated[f]=TVectorGfxPoint.Create(p.x,p.y)
- Next
-
- For Local l:TVectorGfxLine=EachIn lines
- Static.linedraw.LineToCollisionMap(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,0,Self,0,Null,True,Null)
- Next
- End Method
-
- Rem
- bbdoc: Draw the object, using the collision map routines.
- returns: A bitmask of collisions.
- about: Draws the object. If @colmap is null then no collision processing takes place.
- about: If @actor is true then collision processing takes place, but the object will
- about: not write into the collision map.
- about: If @list is not null then any collisions will be written into this list. This only applies if @colmap is set and @actor true.
- EndRem
- Method DrawToCollisionMap:Int(colmap:TVectorGfxCollisionMap=Null, actor:Int=False, list:TList=Null)
- Local col:Int=0
-
- rotated=New TVectorGfxPoint[points.length]
-
- For Local f:Int=0 Until points.length
- Local p:TAlgoPointD=DoRotateD(points[f].x*scale,points[f].y*scale,ang)
- rotated[f]=TVectorGfxPoint.Create(p.x,p.y)
- Next
-
- Local i:Int=0
-
- For Local l:TVectorGfxLine=EachIn lines
- col:|Static.linedraw.LineToCollisionMap(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,l.id,Self,i,colmap,actor,list)
- i:+1
- Next
-
- Return col
- End Method
-
- Rem
- bbdoc: Draw the object, using returning a point list.
- returns: The list of points plotted as @TVectorGfxPoint objects.
- EndRem
- Method DrawToPointList:TList()
- Local list:TList=CreateList()
- Local col:Int=0
-
- rotated=New TVectorGfxPoint[points.length]
-
- For Local f:Int=0 Until points.length
- Local p:TAlgoPointD=DoRotateD(points[f].x*scale,points[f].y*scale,ang)
- rotated[f]=TVectorGfxPoint.Create(p.x,p.y)
- Next
-
- Local i:Int=0
-
- For Local l:TVectorGfxLine=EachIn lines
- col:|Static.linedraw.LineToPointList(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,list)
- i:+1
- Next
-
- Return list
- End Method
-End Type
-
-Rem
-bbdoc: Defines a point
-EndRem
-Type TVectorGfxPoint
- Rem
- bbdoc: The X co-ordinate of the point
- EndRem
- Field x:Int
- Rem
- bbdoc: The Y co-ordinate of the point
- EndRem
- Field y:Int
-
- Rem
- bbdoc: Create a point.
- returns: The created point.
- about: @x and @y are the co-ordinates of the point.
- EndRem
- Function Create:TVectorGfxPoint(x:Int, y:Int)
- Local o:TVectorGfxPoint=New TVectorGfxPoint
- o.x=x
- o.y=y
- Return o
- End Function
-
- Function Load:TVectorGfxPoint(s:TStream)
- Local o:TVectorGfxPoint
- o=New TVectorGfxPoint
- o.x=s.ReadInt()
- o.y=s.ReadInt()
- Return o
- End Function
-
- Method Save(s:TStream)
- s.WriteInt(x)
- s.WriteInt(y)
- End Method
-End Type
-
-Rem
-bbdoc: Defines a line
-EndRem
-Type TVectorGfxLine
- Field i1:Int
- Field i2:Int
- Field id:Int
- Field r:Int
- Field g:Int
- Field b:Int
-
- Rem
- bbdoc: Create a line.
- returns: The created line.
- about: @i1 and @i2 are the indexes into the point list. @r, @g and @b is the line's colour. @id is the collision map mask for the line.
- EndRem
- Function Create:TVectorGfxLine(i1:Int, i2:Int, r:Int, g:Int, b:Int, id:Int)
- Local o:TVectorGfxLine=New TVectorGfxLine
-
- o.i1=i1
- o.i2=i2
- o.r=r
- o.g=g
- o.b=b
- o.id=id
-
- Return o
- End Function
-
- Function Load:TVectorGfxLine(s:TStream)
- Local o:TVectorGfxLine
- o=New TVectorGfxLine
- o.i1=s.ReadInt()
- o.i2=s.ReadInt()
- o.r=s.ReadInt()
- o.g=s.ReadInt()
- o.b=s.ReadInt()
- o.id=s.ReadInt()
- Return o
- End Function
-
- Method Save:TVectorGfxLine(s:TStream)
- s.WriteInt(i1)
- s.WriteInt(i2)
- s.WriteInt(r)
- s.WriteInt(g)
- s.WriteInt(b)
- s.WriteInt(id)
- End Method
-End Type
-
-Private
-
-Type Static
- Global linedraw:TVectorGfxLineStyle
-
- Function Init()
- linedraw=New LineSolid
- End Function
-End Type
-
-Type LineSolid Extends TVectorGfxLineStyle
- Method LineToCollisionMap:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList)
- Local mask:Int=0
- Local lp:TList=DoLine(x1,y1,x2,y2)
-
- SetColor(r,g,b)
-
- For Local p:TAlgoPoint=EachIn lp
- If colmap
- If actor
- Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y)
-
- If c
- mask:|c.mask
- If list
- list.AddLast(c)
- EndIf
- EndIf
- Else
- mask:|colmap.SetCollision(p.x,p.y,id,obj,line)
- EndIf
- EndIf
- Plot(p.x,p.y)
- Next
-
- Return mask
- End Method
-
- Method LineToPointList:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, list:TList)
- Local mask:Int=0
- Local lp:TList=DoLine(x1,y1,x2,y2)
-
- SetColor(r,g,b)
-
- For Local p:TAlgoPoint=EachIn lp
- Plot(p.x,p.y)
- list.AddLast(TVectorGfxPoint.Create(p.x,p.y))
- Next
-
- Return mask
- End Method
-End Type
-
-Static.Init()
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.vectorgfx
+EndRem
+Module noddybox.vectorgfx
+
+ModuleInfo "Framework: 2D Vector Graphics classes"
+ModuleInfo "Copyright: Ian Cowburn -- released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+Import brl.linkedlist
+Import brl.math
+Import brl.endianstream
+Import brl.max2d
+Import noddybox.vector
+Import noddybox.algorithm
+
+Rem
+bbdoc: Wibble
+about: Wobble
+EndRem
+
+Rem
+bbdoc: Defines a method for drawing vector lines
+about: For an example of creating a line drawing routine view the LineSolid type in the private section of this module.
+EndRem
+Type TVectorGfxLineStyle Abstract
+ Rem
+ bbdoc: Draws a vector line using IDs and @TVectorGfxCollisionMap method.
+ returns: The or'ed mask of all collision IDs overwritten in @colmap by this line, or zero if @colmap is null.
+ about: This routine must draw a line from @x1, @y1 to @x2, @y2 using the colour @r,@g,@b.
+ about: @id, @obj and @line must be written into the collision map @colmap if @colmap is not null and @actor is false.
+ about: If @colmap is set and @actor true, then collisions must be returned but no points written into the collision map.
+ about: If @colmap is set, @actor is true and @list is not null then any collisions should be recorded into this list
+ about: (no requirement for duplicate checking).
+ EndRem
+ Method LineToCollisionMap:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList) Abstract
+
+ Rem
+ bbdoc: Draws a vector line using the point list method.
+ about: This routine must draw a line from @x1, @y1 to @x2, @y2 using the colour @r,@g,@b.
+ about: If list is not null, then the points drawn must be stored in the list as @TVectorGfxPoint objects.
+ about: For an example of creating a line drawing routine view the LineSolid type in the private section of this module.
+ EndRem
+ Method LineToPointList:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, list:TList) Abstract
+End Type
+
+Rem
+bbdoc: Set to use solid lines for drawing.
+about: This mode draws vector lines as solid colour lines using the current alpha, and is the default mode.
+EndRem
+Function VectorGfxSetSolid()
+ Static.linedraw=New LineSolid
+End Function
+
+Rem
+bbdoc: Set to use a custom drawing method.
+EndRem
+Function VectorGfxSetCustom(linedraw:TVectorGfxLineStyle)
+ Static.linedraw=linedraw
+End Function
+
+Rem
+bbdoc: Defines a point in the vector graphics collision map.
+EndRem
+Type TVectorGfxCollision
+ Rem
+ bbdoc: The X co-ordinate of this collision (in the object co-ordinate space).
+ EndRem
+ Field x:Int
+
+ Rem
+ bbdoc: The Y co-ordinate of this collision (in the object co-ordinate space).
+ EndRem
+ Field y:Int
+
+ Rem
+ bbdoc: The collision masks at this point.
+ EndRem
+ Field mask:Int
+
+ Rem
+ bbdoc: The last vector object that wrote at this point.
+ EndRem
+ Field obj:TVectorGfxObject
+
+ Rem
+ bbdoc: The index of the line in the last vector object that wrote at this point.
+ EndRem
+ Field line:Int
+
+ Function Create:TVectorGfxCollision(x:Int, y:Int, mask:Int, obj:TVectorGfxObject, line:Int)
+ Local o:TVectorGfxCollision=New TVectorGfxCollision
+ o.x=x
+ o.y=y
+ o.mask=mask
+ o.obj=obj
+ o.line=line
+ Return o
+ End Function
+End Type
+
+
+Rem
+bbdoc: Defines a vector graphics collision map.
+about: Collisions using this method in the library are defined using a bitmask (allowing 32 collision masks).
+EndRem
+Type TVectorGfxCollisionMap
+
+ Field width:Int
+ Field height:Int
+ Field xoff:Int
+ Field yoff:Int
+ Field data:TVectorGfxCollision[,]
+
+ Rem
+ bbdoc: Create a collision map.
+ returns: The created collision map.
+ about: @width and @height are the size of the collision map.
+ EndRem
+ Function Create:TVectorGfxCollisionMap(width:Int, height:Int)
+ Local o:TVectorGfxCollisionMap=New TVectorGfxCollisionMap
+
+ o.width=width
+ o.height=height
+ o.xoff=0
+ o.yoff=0
+ o.Clear()
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Set the offset of the collision map.
+ about: @x and @y are the offsets into the co-ordinate space where the collision map lives.
+ EndRem
+ Method SetOffset(x:Int, y:Int)
+ xoff=x
+ yoff=y
+ End Method
+
+ Rem
+ bbdoc: Get a collision point.
+ returns: The collision point, or null if nothing drawn there.
+ about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space)
+ EndRem
+ Method GetCollision:TVectorGfxCollision(x:Int, y:Int)
+ If x<xoff Or x>=xoff+width Or y<yoff Or y>=yoff+height
+ Return Null
+ Else
+ Return data[x-xoff,y-yoff]
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Set a collision point.
+ returns: The current collision mask for that point, or zero if the point is out of the map's range.
+ about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space)
+ EndRem
+ Method SetCollision:Int(x:Int, y:Int, id:Int, obj:TVectorGfxObject, line:Int)
+ If x<xoff Or x>=xoff+width Or y<yoff Or y>=yoff+height
+ Return 0
+ EndIf
+
+ Local ax:Int=x-xoff
+ Local ay:Int=y-yoff
+
+ Local cur:TVectorGfxCollision=data[ax,ay]
+
+ If Not cur
+ cur=TVectorGfxCollision.Create(x,y,id,obj,line)
+ data[ax,ay]=cur
+ Else
+ cur.mask:|id
+ cur.obj=obj
+ cur.line=line
+ EndIf
+
+ Return cur.mask
+ End Method
+
+ Rem
+ bbdoc: Clear the collision map
+ EndRem
+ Method Clear()
+ data=New TVectorGfxCollision[width,height]
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a 2D vector graphics object
+EndRem
+Type TVectorGfxObject
+ Rem
+ bbdoc: The points making up this object
+ EndRem
+ Field points:TVectorGfxPoint[]
+ Rem
+ bbdoc: The lines making up this object
+ EndRem
+ Field lines:TVectorGfxLine[]
+ Rem
+ bbdoc: The X co-ordinate of the object
+ EndRem
+ Field x:Int
+ Rem
+ bbdoc: The Y co-ordinate of the object
+ EndRem
+ Field y:Int
+ Rem
+ bbdoc: The minimum X co-ordinate of the object. Only valid after a call to SetPoints().
+ EndRem
+ Field min_x:Int
+ Rem
+ bbdoc: The maximum X co-ordinate of the object. Only valid after a call to SetPoints().
+ EndRem
+ Field max_x:Int
+ Rem
+ bbdoc: The minimum Y co-ordinate of the object. Only valid after a call to SetPoints().
+ EndRem
+ Field min_y:Int
+ Rem
+ bbdoc: The maximum Y co-ordinate of the object. Only valid after a call to SetPoints().
+ EndRem
+ Field max_y:Int
+ Rem
+ bbdoc: The width of the object. Only valid after a call to SetPoints().
+ EndRem
+ Field width:Int
+ Rem
+ bbdoc: The height of the object. Only valid after a call to SetPoints().
+ EndRem
+ Field height:Int
+ Rem
+ bbdoc: The angle of the object, as degrees*10. Must be within the range 0-3599 inclusive.
+ EndRem
+ Field ang:Int
+ Rem
+ bbdoc: The scale of the object.
+ EndRem
+ Field scale:Double
+
+ Field rotated:TVectorGfxPoint[]
+
+ Rem
+ bbdoc: Creates a new empty object
+ returns: The created object.
+ EndRem
+ Method New()
+ points=Null
+ lines=Null
+ rotated=Null
+ x=0
+ y=0
+ min_x=9999999
+ min_y=9999999
+ max_x=-9999999
+ max_y=-9999999
+ width=0
+ height=0
+ ang=0
+ scale=1
+ End Method
+
+ Rem
+ bbdoc: Clones this object
+ about: Returns a copy of this object, with its own copy of the line and points.
+ EndRem
+ Method Clone:TVectorGfxObject()
+ Local o:TVectorGfxObject=New TVectorGfxObject
+ o.x=x
+ o.y=y
+ o.min_x=min_x
+ o.min_y=min_y
+ o.max_x=max_x
+ o.max_y=max_y
+ o.width=width
+ o.height=height
+ o.ang=ang
+ o.scale=scale
+ o.SetPoints(points)
+ o.SetLines(lines)
+ Return o
+ End Method
+
+ Rem
+ bbdoc: Sets the points for this object
+ about: @pa is an array of points for this object.
+ EndRem
+ Method SetPoints(pa:Object[])
+ points=New TVectorGfxPoint[pa.length]
+ For Local f:Int=0 Until pa.length
+ points[f]=TVectorGfxPoint(pa[f])
+ min_x=Min(min_x,points[f].x)
+ min_y=Min(min_y,points[f].y)
+ max_x=Max(max_x,points[f].x)
+ max_y=Max(max_y,points[f].y)
+ Next
+ width=max_x-min_x
+ height=max_y-min_y
+ End Method
+
+ Rem
+ bbdoc: Sets the lines for this object.
+ about: @la is the array of lines for this object.
+ EndRem
+ Method SetLines(la:Object[])
+ lines=New TVectorGfxLine[la.length]
+ For Local f:Int=0 Until la.length
+ lines[f]=TVectorGfxLine(la[f])
+ Next
+ End Method
+
+ Rem
+ bbdoc: Whether a point is inside the object
+ returns: True if the point lies inside the object. The object is assumed to be a closed polygon for this test.
+ about: @cx, @cy is the point to test.
+ about: This routine is based on code from comp.graphics.algorithms FAQ 2.03
+ EndRem
+ Method IsInside:Int(cx:Int, cy:Int)
+ If rotated=Null
+ Return False
+ EndIf
+
+ Local cross:Int=False
+
+ For Local l:TVectorGfxLine=EachIn lines
+ Local x1:Int=x+rotated[l.i1].x
+ Local y1:Int=y+rotated[l.i1].y
+ Local x2:Int=x+rotated[l.i2].x
+ Local y2:Int=y+rotated[l.i2].y
+
+ If ((((y1<=cy) And (cy<y2)) Or ((y2<=cy) And (cy<y1))) And (cx < (x2 - x1) * (cy - y1) / (y2 - y1) + x1))
+ cross=Not cross
+ EndIf
+ Next
+
+ Return cross
+ End Method
+
+ Rem
+ bbdoc: A line's adjusted co-ordinates.
+ returns: The rotated and scaled points (in object co-ordinates) of the line.
+ about: @i is the index of the line to return the points for.
+ about: Calling it before drawing the object will return null.
+ EndRem
+ Method AdjustedCoords:TVectorGfxPoint[](i:Int)
+ If rotated=Null
+ Return Null
+ EndIf
+
+ Local p:TVectorGfxPoint[]=New TVectorGfxPoint[2]
+ Local l:TVectorGfxLine=lines[i]
+ p[0]=rotated[l.i1]
+ p[1]=rotated[l.i2]
+ Return p
+ End Method
+
+ Rem
+ bbdoc: A line's normal.
+ returns: The normal of the selected line.
+ about: @i is the index of the line to return the normal of. This will return the normal due to the rotation of the object after the object is drawn.
+ about: Calling it before drawing the object will return null.
+ EndRem
+ Method Normal:TVector(i:Int)
+ If rotated=Null
+ Return Null
+ EndIf
+
+ Local l:TVectorGfxLine=lines[i]
+ Local v:TVector=TVector.Create(rotated[l.i2].y-rotated[l.i1].y,rotated[l.i1].x-rotated[l.i2].x)
+ v.Normalise()
+ Return v
+ End Method
+
+ Rem
+ bbdoc: Loads the object from the supplied @filename.
+ returns: The loaded object, or null if the file could not be opened.
+ EndRem
+ Function Load:TVectorGfxObject(filename:String)
+ Local s:TStream=ReadStream(filename)
+
+ If Not s
+ Return Null
+ EndIf
+
+ s=LittleEndianStream(s)
+ Local o:TVectorGfxObject=New TVectorGfxObject
+
+ o.x=s.ReadInt()
+ o.y=s.ReadInt()
+ o.ang=s.ReadInt()
+
+ Local l:TList=CreateList()
+ Local i:Int=s.ReadInt()
+
+ For Local f=0 Until i
+ l.AddLast(TVectorGfxPoint.Load(s))
+ Next
+
+ o.SetPoints(l.ToArray())
+
+ l.Clear()
+
+ i=s.ReadInt()
+
+ For Local f=0 Until i
+ l.AddLast(TVectorGfxLine.Load(s))
+ Next
+
+ o.SetLines(l.ToArray())
+
+ s.Close()
+
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Saves the object to the supplied @filename.
+ EndRem
+ Method Save(filename:String)
+ Local s:TStream=WriteStream(filename)
+
+ If Not s
+ Return Null
+ EndIf
+
+ s=LittleEndianStream(s)
+
+ s.WriteInt(x)
+ s.WriteInt(y)
+ s.WriteInt(ang)
+
+ s.WriteInt(points.length)
+ For Local p:TVectorGfxPoint=EachIn points
+ p.Save(s)
+ Next
+
+ s.WriteInt(lines.length)
+ For Local l:TVectorGfxLine=EachIn lines
+ l.Save(s)
+ Next
+
+ s.Close()
+ End Method
+
+ Rem
+ bbdoc: Draw the object, not bothering about collisions.
+ EndRem
+ Method Draw()
+ rotated=New TVectorGfxPoint[points.length]
+
+ For Local f:Int=0 Until points.length
+ Local p:TAlgoPointD=DoRotateD(points[f].x*scale,points[f].y*scale,ang)
+ rotated[f]=TVectorGfxPoint.Create(p.x,p.y)
+ Next
+
+ For Local l:TVectorGfxLine=EachIn lines
+ Static.linedraw.LineToCollisionMap(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,0,Self,0,Null,True,Null)
+ Next
+ End Method
+
+ Rem
+ bbdoc: Draw the object, using the collision map routines.
+ returns: A bitmask of collisions.
+ about: Draws the object. If @colmap is null then no collision processing takes place.
+ about: If @actor is true then collision processing takes place, but the object will
+ about: not write into the collision map.
+ about: If @list is not null then any collisions will be written into this list. This only applies if @colmap is set and @actor true.
+ EndRem
+ Method DrawToCollisionMap:Int(colmap:TVectorGfxCollisionMap=Null, actor:Int=False, list:TList=Null)
+ Local col:Int=0
+
+ rotated=New TVectorGfxPoint[points.length]
+
+ For Local f:Int=0 Until points.length
+ Local p:TAlgoPointD=DoRotateD(points[f].x*scale,points[f].y*scale,ang)
+ rotated[f]=TVectorGfxPoint.Create(p.x,p.y)
+ Next
+
+ Local i:Int=0
+
+ For Local l:TVectorGfxLine=EachIn lines
+ col:|Static.linedraw.LineToCollisionMap(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,l.id,Self,i,colmap,actor,list)
+ i:+1
+ Next
+
+ Return col
+ End Method
+
+ Rem
+ bbdoc: Draw the object, using returning a point list.
+ returns: The list of points plotted as @TVectorGfxPoint objects.
+ EndRem
+ Method DrawToPointList:TList()
+ Local list:TList=CreateList()
+ Local col:Int=0
+
+ rotated=New TVectorGfxPoint[points.length]
+
+ For Local f:Int=0 Until points.length
+ Local p:TAlgoPointD=DoRotateD(points[f].x*scale,points[f].y*scale,ang)
+ rotated[f]=TVectorGfxPoint.Create(p.x,p.y)
+ Next
+
+ Local i:Int=0
+
+ For Local l:TVectorGfxLine=EachIn lines
+ col:|Static.linedraw.LineToPointList(x+rotated[l.i1].x,y+rotated[l.i1].y,x+rotated[l.i2].x,y+rotated[l.i2].y,l.r,l.g,l.b,list)
+ i:+1
+ Next
+
+ Return list
+ End Method
+End Type
+
+Rem
+bbdoc: Defines a point
+EndRem
+Type TVectorGfxPoint
+ Rem
+ bbdoc: The X co-ordinate of the point
+ EndRem
+ Field x:Int
+ Rem
+ bbdoc: The Y co-ordinate of the point
+ EndRem
+ Field y:Int
+
+ Rem
+ bbdoc: Create a point.
+ returns: The created point.
+ about: @x and @y are the co-ordinates of the point.
+ EndRem
+ Function Create:TVectorGfxPoint(x:Int, y:Int)
+ Local o:TVectorGfxPoint=New TVectorGfxPoint
+ o.x=x
+ o.y=y
+ Return o
+ End Function
+
+ Function Load:TVectorGfxPoint(s:TStream)
+ Local o:TVectorGfxPoint
+ o=New TVectorGfxPoint
+ o.x=s.ReadInt()
+ o.y=s.ReadInt()
+ Return o
+ End Function
+
+ Method Save(s:TStream)
+ s.WriteInt(x)
+ s.WriteInt(y)
+ End Method
+End Type
+
+Rem
+bbdoc: Defines a line
+EndRem
+Type TVectorGfxLine
+ Field i1:Int
+ Field i2:Int
+ Field id:Int
+ Field r:Int
+ Field g:Int
+ Field b:Int
+
+ Rem
+ bbdoc: Create a line.
+ returns: The created line.
+ about: @i1 and @i2 are the indexes into the point list. @r, @g and @b is the line's colour. @id is the collision map mask for the line.
+ EndRem
+ Function Create:TVectorGfxLine(i1:Int, i2:Int, r:Int, g:Int, b:Int, id:Int)
+ Local o:TVectorGfxLine=New TVectorGfxLine
+
+ o.i1=i1
+ o.i2=i2
+ o.r=r
+ o.g=g
+ o.b=b
+ o.id=id
+
+ Return o
+ End Function
+
+ Function Load:TVectorGfxLine(s:TStream)
+ Local o:TVectorGfxLine
+ o=New TVectorGfxLine
+ o.i1=s.ReadInt()
+ o.i2=s.ReadInt()
+ o.r=s.ReadInt()
+ o.g=s.ReadInt()
+ o.b=s.ReadInt()
+ o.id=s.ReadInt()
+ Return o
+ End Function
+
+ Method Save:TVectorGfxLine(s:TStream)
+ s.WriteInt(i1)
+ s.WriteInt(i2)
+ s.WriteInt(r)
+ s.WriteInt(g)
+ s.WriteInt(b)
+ s.WriteInt(id)
+ End Method
+End Type
+
+Private
+
+Type Static
+ Global linedraw:TVectorGfxLineStyle
+
+ Function Init()
+ linedraw=New LineSolid
+ End Function
+End Type
+
+Type LineSolid Extends TVectorGfxLineStyle
+ Method LineToCollisionMap:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, obj:TVectorGfxObject, line:Int, colmap:TVectorGfxCollisionMap, actor:Int, list:TList)
+ Local mask:Int=0
+ Local lp:TList=DoLine(x1,y1,x2,y2)
+
+ SetColor(r,g,b)
+
+ For Local p:TAlgoPoint=EachIn lp
+ If colmap
+ If actor
+ Local c:TVectorGfxCollision=colmap.GetCollision(p.x,p.y)
+
+ If c
+ mask:|c.mask
+ If list
+ list.AddLast(c)
+ EndIf
+ EndIf
+ Else
+ mask:|colmap.SetCollision(p.x,p.y,id,obj,line)
+ EndIf
+ EndIf
+ Plot(p.x,p.y)
+ Next
+
+ Return mask
+ End Method
+
+ Method LineToPointList:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, list:TList)
+ Local mask:Int=0
+ Local lp:TList=DoLine(x1,y1,x2,y2)
+
+ SetColor(r,g,b)
+
+ For Local p:TAlgoPoint=EachIn lp
+ Plot(p.x,p.y)
+ list.AddLast(TVectorGfxPoint.Create(p.x,p.y))
+ Next
+
+ Return mask
+ End Method
+End Type
+
+Static.Init()
diff --git a/win32.mod/win32.bmx b/win32.mod/win32.bmx
index 11b6512..edb1d0c 100644
--- a/win32.mod/win32.bmx
+++ b/win32.mod/win32.bmx
@@ -1,113 +1,111 @@
-' Copyright (c) 2006 Ian Cowburn
-'
-' Permission is hereby granted, free of charge, to any person obtaining a copy of
-' this software and associated documentation files (the "Software"), to deal in
-' the Software without restriction, including without limitation the rights to
-' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-' of the Software, and to permit persons to whom the Software is furnished to do
-' so, subject to the following conditions:
-'
-' The above copyright notice and this permission notice shall be included in all
-' copies or substantial portions of the Software.
-'
-' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-' SOFTWARE.
-'
-' $Id$
-'
-Rem
-bbdoc: noddybox.win32
-EndRem
-Module noddybox.win32
-
-ModuleInfo "Framework: Some routines I wanted from the Windows API"
-ModuleInfo "Copyright: Ian Cowburn -- Released under the MIT License"
-ModuleInfo "Author: Ian Cowburn"
-ModuleInfo "Version: $Revision$"
-
-Strict
-
-?Win32
-Import "noddybox.win32.c"
-?
-
-Rem
-bbdoc: Returned from GetDriveType() for unknown types.
-EndRem
-Const DRIVETYPE_UNKNOWN:Int=0
-Rem
-bbdoc: Returned from GetDriveType() for invalid root paths.
-EndRem
-Const DRIVETYPE_NO_ROOT_DIR:Int=1
-Rem
-bbdoc: Returned from GetDriveType() for removeable drives.
-EndRem
-Const DRIVETYPE_REMOVABLE:Int=2
-Rem
-bbdoc: Returned from GetDriveType() for fixed drives.
-EndRem
-Const DRIVETYPE_FIXED:Int=3
-Rem
-bbdoc: Returned from GetDriveType() for networked drives.
-EndRem
-Const DRIVETYPE_REMOTE:Int=4
-Rem
-bbdoc: Returned from GetDriveType() for CD-ROM drives.
-EndRem
-Const DRIVETYPE_CDROM:Int=5
-Rem
-bbdoc: Returned from GetDriveType() for RAM disks.
-EndRem
-Const DRIVETYPE_RAMDISK:Int=6
-
-Rem
-bbdoc: Returns a bitmask of the drives on the system
-about: Returns a bitmask where a bit set indicates the presence of a drive letter. Bit 0 is A:, 1 is B: and so on.
-about: On Linux and MacOS should return 0.
-EndRem
-Function W32GetLogicalDrives:Int()
- Return W32GetLogicalDrives_C()
-End Function
-
-Rem
-bbdoc: Returns a drive type
-about: Returns a DRIVETYPE_ constants given a root path in @root
-about: On Linux and MacOS should return DRIVETYPE_UNKNOWN.
-EndRem
-Function W32GetDriveType:Int(root:String)
- Return W32GetDriveType_C(root.ToCString())
-End Function
-
-Private
-
-?Win32
-Extern
- Function W32GetLogicalDrives_C:Int()
-
- Rem
- bbdoc: Returns a drive type
- about: Returns a DRIVETYPE_ constants given a root path in @root
- about: On Linux and MacOS should return DRIVETYPE_UNKNOWN.
- EndRem
- Function W32GetDriveType_C:Int(root:Byte Ptr)
-EndExtern
-?Linux
-Function W32GetLogicalDrives_C:Int()
- Return 0
-End Function
-Function W32GetDriveType_C:Int(root:Byte Ptr)
- Return DRIVETYPE_UNKNOWN
-End Function
-?MacOS
-Function W32GetLogicalDrives_C:Int()
- Return 0
-End Function
-Function W32GetDriveType_C:Int(root:Byte Ptr)
- Return DRIVETYPE_UNKNOWN
-End Function
-?
+' Copyright (c) 2006 Ian Cowburn
+'
+' Permission is hereby granted, free of charge, to any person obtaining a copy of
+' this software and associated documentation files (the "Software"), to deal in
+' the Software without restriction, including without limitation the rights to
+' use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+' of the Software, and to permit persons to whom the Software is furnished to do
+' so, subject to the following conditions:
+'
+' The above copyright notice and this permission notice shall be included in all
+' copies or substantial portions of the Software.
+'
+' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+' SOFTWARE.
+'
+' $Id$
+'
+Rem
+bbdoc: noddybox.win32
+EndRem
+Module noddybox.win32
+
+ModuleInfo "Framework: Some routines I wanted from the Windows API"
+ModuleInfo "Copyright: Ian Cowburn -- Released under the MIT License"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+?Win32
+Import "noddybox.win32.c"
+?
+
+Rem
+bbdoc: Returned from GetDriveType() for unknown types.
+EndRem
+Const DRIVETYPE_UNKNOWN:Int=0
+Rem
+bbdoc: Returned from GetDriveType() for invalid root paths.
+EndRem
+Const DRIVETYPE_NO_ROOT_DIR:Int=1
+Rem
+bbdoc: Returned from GetDriveType() for removeable drives.
+EndRem
+Const DRIVETYPE_REMOVABLE:Int=2
+Rem
+bbdoc: Returned from GetDriveType() for fixed drives.
+EndRem
+Const DRIVETYPE_FIXED:Int=3
+Rem
+bbdoc: Returned from GetDriveType() for networked drives.
+EndRem
+Const DRIVETYPE_REMOTE:Int=4
+Rem
+bbdoc: Returned from GetDriveType() for CD-ROM drives.
+EndRem
+Const DRIVETYPE_CDROM:Int=5
+Rem
+bbdoc: Returned from GetDriveType() for RAM disks.
+EndRem
+Const DRIVETYPE_RAMDISK:Int=6
+
+Rem
+bbdoc: Returns a bitmask of the drives on the system
+about: Returns a bitmask where a bit set indicates the presence of a drive letter. Bit 0 is A:, 1 is B: and so on.
+about: On Linux and MacOS should return 0.
+EndRem
+Function W32GetLogicalDrives:Int()
+ Return W32GetLogicalDrives_C()
+End Function
+
+Rem
+bbdoc: Returns a drive type
+about: Returns a DRIVETYPE_ constants given a root path in @root
+about: On Linux and MacOS should return DRIVETYPE_UNKNOWN.
+EndRem
+Function W32GetDriveType:Int(root:String)
+ Return W32GetDriveType_C(root.ToCString())
+End Function
+
+Private
+
+?Win32
+Extern
+ Function W32GetLogicalDrives_C:Int()
+
+ Rem
+ bbdoc: Returns a drive type
+ about: Returns a DRIVETYPE_ constants given a root path in @root
+ about: On Linux and MacOS should return DRIVETYPE_UNKNOWN.
+ EndRem
+ Function W32GetDriveType_C:Int(root:Byte Ptr)
+EndExtern
+?Linux
+Function W32GetLogicalDrives_C:Int()
+ Return 0
+End Function
+Function W32GetDriveType_C:Int(root:Byte Ptr)
+ Return DRIVETYPE_UNKNOWN
+End Function
+?MacOS
+Function W32GetLogicalDrives_C:Int()
+ Return 0
+End Function
+Function W32GetDriveType_C:Int(root:Byte Ptr)
+ Return DRIVETYPE_UNKNOWN
+End Function
+?