summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2005-10-17 00:00:52 +0000
committerIan C <ianc@noddybox.co.uk>2005-10-17 00:00:52 +0000
commit41b4072c2ab1134b7ebcb7ec86a7e7012af953a7 (patch)
tree891bf0a4f3882ec976f45c841ffded4ab5f5f9e8
parent8a661752eefd670c32e9122ac60a70ceeb701b4a (diff)
Added TTextList, TScrollbar and a simple file selector. Change TFloatNumber to TDoubleNumber.
-rw-r--r--simplegui.mod/simplegui.bmx670
1 files changed, 639 insertions, 31 deletions
diff --git a/simplegui.mod/simplegui.bmx b/simplegui.mod/simplegui.bmx
index 79ba7eb..a6dab25 100644
--- a/simplegui.mod/simplegui.bmx
+++ b/simplegui.mod/simplegui.bmx
@@ -11,8 +11,9 @@ ModuleInfo "Version: $Revision$"
' $Id$
Strict
-Import brl.Max2D
-Import brl.Basic
+Import brl.max2d
+Import brl.filesystem
+Import brl.basic
Import noddybox.bitmapfont
Rem
@@ -31,7 +32,24 @@ EndRem
Type TWidget Abstract
Rem
- bbdoc: If true the widget is displayed and can be used.
+ bbdoc: This widget consumes click events
+ EndRem
+ Const HAS_CLICK:Int=1
+ Rem
+ bbdoc: This widget consumes drag events
+ EndRem
+ Const HAS_DRAG:Int=2
+ Rem
+ bbdoc: This widget consumes key events
+ EndRem
+ Const HAS_KEY:Int=4
+
+ Rem
+ bbdoc: If true the widget is displayed.
+ EndRem
+ Field displayed:Int
+ Rem
+ bbdoc: If true the widget can be interacted with.
EndRem
Field enabled:Int
Rem
@@ -67,7 +85,7 @@ Type TWidget Abstract
EndRem
Field owner:TGUIHandler
Rem
- bbdoc: True if this widget consumes events, False otherwise.
+ bbdoc: The mask of consumed events, zero otherwise.
EndRem
Field consumes:Int
@@ -81,7 +99,9 @@ Type TWidget Abstract
bbdoc: Override this for when the mouse enters. Call this parent version to handle @mouse_over too.
EndRem
Method MouseEnter()
- mouse_over=True
+ If displayed And enabled
+ mouse_over=True
+ EndIf
End Method
Rem
@@ -98,6 +118,13 @@ Type TWidget Abstract
End Method
Rem
+ bbdoc: Handles mouse dragging.
+ about: @mx and @my are the changes in mouse co-ordinates since the last drag.
+ EndRem
+ Method HandleDrag(mx:Int, my:Int)
+ End Method
+
+ Rem
bbdoc: Must be provided by a widget to draw itself.
EndRem
Method Draw() Abstract
@@ -158,8 +185,9 @@ Type TPanel Extends TWidget
EndRem
Function Create:TPanel(gui:TGUIHandler,x:Int, y:Int, w:Int, h:Int)
Local o:TPanel=New TPanel
+ o.displayed=True
o.enabled=True
- o.consumes=False
+ o.consumes=0
If x=-1
x=(GraphicsWidth()-w)/2
@@ -197,8 +225,9 @@ Type TLabel Extends TWidget
EndRem
Function Create:TLabel(gui:TGUIHandler,x:Int, y:Int, text:String)
Local o:TLabel=New TLabel
+ o.displayed=True
o.enabled=True
- o.consumes=False
+ o.consumes=0
o.x=x
o.y=y
o.w=TGUIFont.font.TextWidth(text)+2
@@ -241,6 +270,16 @@ Type TText Extends TWidget
EndRem
Const POSITIVE:Int=4
+ Rem
+ bbdoc: The text box handles a basic set of filename characters (alphanumerics, periods, spaces and underscores)
+ EndRem
+ Const FILENAME:Int=8
+
+ Rem
+ bbdoc: The text box is readonly
+ EndRem
+ Const READONLY:Int=256
+
Rem
bbdoc: Create a TText widget.
@@ -251,8 +290,9 @@ Type TText Extends TWidget
EndRem
Function Create:TText(gui:TGUIHandler,x:Int, y:Int, text:String, maxlen:Int, mode:Int=0, callback(w:TWidget)=Null)
Local o:TText=New TText
+ o.displayed=True
o.enabled=True
- o.consumes=True
+ o.consumes=HAS_CLICK|HAS_KEY
o.x=x
o.y=y
o.maxlen=maxlen
@@ -287,10 +327,16 @@ Type TText Extends TWidget
End Method
Method HandleClick()
- owner.SetFocus(Self)
+ If Not(mode & READONLY)
+ owner.SetFocus(Self)
+ EndIf
End Method
Method HandleKey(k:Int)
+ If (mode & READONLY)
+ Return
+ EndIf
+
If k=27
text=""
Else If k=8
@@ -316,7 +362,13 @@ Type TText Extends TWidget
text:+Chr(k)
EndIf
Else
- text:+Chr(k)
+ If (mode & FILENAME)
+ If (k>=Asc("a") And k<=Asc("z")) Or (k>=Asc("A") And k<=Asc("Z")) Or (k>=Asc("0") And k<=Asc("9")) Or k=Asc(" ") Or k=Asc(".") Or k=Asc("_")
+ text:+Chr(k)
+ EndIf
+ Else
+ text:+Chr(k)
+ EndIf
EndIf
EndIf
End Method
@@ -324,7 +376,7 @@ Type TText Extends TWidget
Method Draw()
Local s:String=text
- If owner.GetFocus()=Self
+ If owner.GetFocus()=Self And Not (mode & READONLY)
SetColor(128,128,128)
s:+"_"
Else
@@ -355,8 +407,9 @@ Type TCheckbox Extends TWidget
EndRem
Function Create:TCheckbox(gui:TGUIHandler, x:Int, y:Int, text:String, callback(w:TWidget)=Null)
Local o:TCheckbox=New TCheckbox
+ o.displayed=True
o.enabled=True
- o.consumes=True
+ o.consumes=HAS_CLICK
o.x=x
o.y=y
o.w=TGUIFont.font.TextWidth(" "+text)+4+TGUIFont.font.MaxHeight()
@@ -409,8 +462,9 @@ Type TButton Extends TWidget
EndRem
Function Create:TButton(gui:TGUIHandler, x:Int, y:Int, w:Int, h:Int, text:String, callback(w:TWidget))
Local o:TButton=New TButton
+ o.displayed=True
o.enabled=True
- o.consumes=True
+ o.consumes=HAS_CLICK
o.x=x
o.y=y
o.w=w
@@ -462,8 +516,9 @@ Type TButtonList Extends TWidget
Function Create:TButtonList(gui:TGUIHandler, x:Int, y:Int, options:String[], selected:Int, callback(w:TWidget))
Local o:TButtonList=New TButtonList
Local maxw:Int=0
+ o.displayed=True
o.enabled=True
- o.consumes=True
+ o.consumes=HAS_CLICK
o.x=x
o.y=y
o.options=options
@@ -500,7 +555,7 @@ Type TButtonList Extends TWidget
SetColor(64,64,64)
EndIf
- DrawRect(x,y,w,h)
+ DrawRect(x,y,w,h)
Draw3DBox(x+2,y+2,h-4,h-4,False,1)
TGUIFont.font.Draw(text,x+TGUIFont.font.MaxHeight()+3,y+1)
@@ -508,29 +563,224 @@ Type TButtonList Extends TWidget
End Type
Rem
-bbdoc: A number up/down widget for floats
+bbdoc: Optional type to use for TTextList
+about: If the objects stored as TTextList options are derived from this type then tabular lists can be created.
+EndRem
+Type TTextListItem Abstract
+ Rem
+ about: The number of columns.
+ returns: The number of columns
+ EndRem
+ Method Columns:Int() Abstract
+
+ Rem
+ about: A column offset.
+ returns: The column offset for column @i (numbered from zero).
+ EndRem
+ Method ColumnOffset:Int(i:Int) Abstract
+
+ Rem
+ about: Column data.
+ returns: The column data for column @i (numbered from zero).
+ EndRem
+ Method ColumnData:String(i:Int) Abstract
+End Type
+
+Rem
+bbdoc: A widget that displays text items as a list.
EndRem
-Type TNumberFloat Extends TWidget
+Type TTextList Extends TWidget
+
+ Field options:Object[]
+ Field selected:Int
+ Field num:Int
+ Field top:Int
+ Field rows:Int
+
+ Rem
+ bbdoc: Create a TTextList widget.
+ returns: The created widget.
+ about: @gui is the @TGUIHandler object managing this wiget. @x, @y, and @w are its position and width.
+ about: @rows are the number of items to display at a time.
+ about: @callback is called when the selection changes.
+ EndRem
+ Function Create:TTextList(gui:TGUIHandler, x:Int, y:Int, w:Int, rows:Int, callback(w:TWidget)=Null)
+ Local o:TTextList=New TTextList
+ Local maxw:Int=0
+ o.displayed=True
+ o.enabled=True
+ o.consumes=HAS_CLICK
+ o.x=x
+ o.y=y
+ o.options=Null
+ o.selected=-1
+ o.num=0
+ o.top=0
+ o.rows=rows
+
+ o.w=w
+ o.h=TGUIFont.font.MaxHeight()*rows
+ o.callback=callback
+ gui.Register(o)
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Sets the options to display in the list.
+ about: @opts is an array of objects. <i>Note</i>: If the objects passed are derived from TTextListItem then tabular output is generated.
+ about: If they are not derived, ToString() is called on the objects to display them, so you are not restricted to the type of object that
+ about: can be passed.
+ EndRem
+ Method SetOptions(opts:Object[])
+ options=opts
+ num=opts.length
+ selected=-1
+ top=0
+ End Method
+
+ Rem
+ bbdoc: Gets the selected item's index.
+ returns: The selected item's index, or -1 if nothing is selected.
+ EndRem
+ Method GetSelectedIndex:Int()
+ Return selected
+ End Method
+
+ Rem
+ bbdoc: Gets the selected item.
+ returns: The selected item, or null if nothing is selected.
+ EndRem
+ Method GetSelectedItem:Object()
+ If options<>Null And selected<>-1
+ Return options[selected]
+ Else
+ Return Null
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Set the top row.
+ about: @i is the index of the item to display in the first row of the widget.
+ EndRem
+ Method SetTopRow(i:Int)
+ If options<>Null And i<num
+ top=i
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Get the top row.
+ returns: The index of the item displayed in the first row of the widget. -1 if no options are set.
+ EndRem
+ Method GetTopRow:Int()
+ If options<>Null
+ Return top
+ Else
+ Return -1
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Ensure an item is visible.
+ about: @i is the index of the item that is to be made visible.
+ EndRem
+ Method EnsureVisible(i:Int)
+ If options<>Null And i<num
+ If i<top
+ top=i
+ ElseIf i>=top+rows
+ top=Max(0,i-rows+1)
+ EndIf
+ EndIf
+ End Method
+
+ Method HandleClick()
+ If options<>Null
+ Local sel:Int=top+(MouseY()-y)/TGUIFont.font.MaxHeight()
+
+ If sel<num
+ selected=sel
+ If callback<>Null
+ callback(Self)
+ EndIf
+ EndIf
+ EndIf
+ End Method
+
+ Method Draw()
+ SetColor(64,64,64)
+ DrawRect(x,y,w,h)
+
+ If options<>Null
+ Local vx:Int
+ Local vy:Int
+ Local vw:Int
+ Local vh:Int
+
+ GetViewport(vx,vy,vw,vh)
+
+ Local ty:Int=y
+ For Local f:Int=top Until top+rows
+ SetViewport(x,ty,w,TGUIFont.font.MaxHeight())
+
+ If f=selected
+ If mouse_over And MouseY()>=ty And MouseY()<ty+TGUIFont.font.MaxHeight()
+ SetColor(200,128,128)
+ Else
+ SetColor(128,128,128)
+ EndIf
+ DrawRect(x,ty,w,TGUIFont.font.MaxHeight())
+ Else
+ If mouse_over And MouseY()>=ty And MouseY()<ty+TGUIFont.font.MaxHeight() And f<num
+ SetColor(128,0,0)
+ DrawRect(x,ty,w,TGUIFont.font.MaxHeight())
+ EndIf
+ EndIf
+
+ If f<num
+ Local li:TTextListItem=TTextListItem(options[f])
+
+ If li<>Null
+ For Local f:Int=0 Until li.Columns()
+ TGUIFont.font.Draw(li.ColumnData(f),x+li.ColumnOffset(f),ty)
+ Next
+ Else
+ TGUIFont.font.Draw(options[f].ToString(),x,ty)
+ EndIf
+ EndIf
+
+ ty:+TGUIFont.font.MaxHeight()
+ Next
+
+ SetViewport(vx,vy,vw,vh)
+ EndIf
+ End Method
+End Type
+
+Rem
+bbdoc: A number up/down widget for doubles
+EndRem
+Type TNumberDouble Extends TWidget
Rem
bbdoc: The value
EndRem
- Field value:Float
+ Field value:Double
Rem
bbdoc: The increment/decrement
EndRem
- Field change:Float
+ Field change:Double
Rem
bbdoc: The maximum value
EndRem
- Field maxval:Float
+ Field maxval:Double
Rem
bbdoc: The minimum value
EndRem
- Field minval:Float
+ Field minval:Double
Rem
bbdoc: Create a TNumber widget.
@@ -538,10 +788,11 @@ Type TNumberFloat Extends TWidget
about: @gui is the @TGUIHandler object managing this wiget. @x and @y are its position.
about: @callback is called when the value changes.
EndRem
- Function Create:TNumberFloat(gui:TGUIHandler, x:Int, y:Int, callback(w:TWidget)=Null)
- Local o:TNumberFloat=New TNumberFloat
+ Function Create:TNumberDouble(gui:TGUIHandler, x:Int, y:Int, callback(w:TWidget)=Null)
+ Local o:TNumberDouble=New TNumberDouble
+ o.displayed=True
o.enabled=True
- o.consumes=True
+ o.consumes=HAS_CLICK
o.value=0
o.minval=0
o.maxval=100
@@ -556,7 +807,7 @@ Type TNumberFloat Extends TWidget
End Function
Method HandleClick()
- Local old:Float=value
+ Local old:Double=value
If MouseX()<x+w/2
value=Min(value+change,maxval)
@@ -627,8 +878,9 @@ Type TNumberInt Extends TWidget
EndRem
Function Create:TNumberInt(gui:TGUIHandler, x:Int, y:Int, callback(w:TWidget)=Null)
Local o:TNumberInt=New TNumberInt
+ o.displayed=True
o.enabled=True
- o.consumes=True
+ o.consumes=HAS_CLICK
o.value=0
o.minval=0
o.maxval=100
@@ -682,6 +934,124 @@ Type TNumberInt Extends TWidget
End Type
Rem
+bbdoc: A scrollbar widget
+EndRem
+Type TScrollbar Extends TWidget
+
+ Field horiz:Int
+ Field bc:Int
+ Field page:Double
+ Field maxval:Double
+ Field minval:Double
+ Field stepsize:Double
+ Field blocksize:Int
+
+ Rem
+ bbdoc: Create a TVerticalScrollbar widget.
+ returns: The created widget.
+ about: @gui is the @TGUIHandler object managing this wiget. @x, @y, @w and @h are its position and size.
+ about: If @w is greater than height then an horizontal scrollbar is created, otherwise its vertical. @callback is called when the scrollbar moves.
+ EndRem
+ Function Create:TScrollbar(gui:TGUIHandler, x:Int, y:Int, w:Int, h:Int, callback(w:TWidget)=Null)
+ Local o:TScrollbar=New TScrollbar
+ o.displayed=True
+ o.enabled=True
+ o.consumes=HAS_CLICK|HAS_DRAG
+ o.x=x
+ o.y=y
+ o.w=w
+ o.h=h
+ o.horiz=(w>h)
+ o.SetBar(0,100,10)
+ o.callback=callback
+ gui.Register(o)
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Set parameters for scroll bar
+ about: @min_val and @max_val are the values at the top and bottom of the scroll bar. @page_size is the numbers between the two that
+ about: is covered by the block in the scrollbar. <i>Note</i>: The maximum value of @value is @max_val minus @page_size.
+ EndRem
+ Method SetBar(min_val:Double, max_val:Double, page_size:Double)
+ minval=min_val
+ maxval=max_val
+ page=page_size
+
+ If horiz
+ stepsize=(maxval-minval)/w
+ blocksize=Min(w,Max(1,page/stepsize))
+ bc=x
+ Else
+ stepsize=(maxval-minval)/h
+ blocksize=Min(h,Max(1,page/stepsize))
+ bc=y
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Get the current value of the scrollbar.
+ returns: The current position of the scrollbar inbetween the minimum and maximum values.
+ EndRem
+ Method GetValue:Double()
+ If horiz
+ Return minval+(bc-x)*stepsize
+ Else
+ Return minval+(bc-y)*stepsize
+ EndIf
+ End Method
+
+ Rem
+ bbdoc: Sets the current value of the scrollbar.
+ EndRem
+ Method SetValue(val:Double)
+ If horiz
+ bc=Max(x,Min(x+w-blocksize,x+(val-minval)/stepsize))
+ Else
+ bc=Max(y,Min(y+h-blocksize,y+(val-minval)/stepsize))
+ EndIf
+ End Method
+
+ Method HandleClick()
+ Local old:Double=GetValue()
+
+ If horiz
+ bc=Max(x,Min(x+w-blocksize,MouseX()))
+ Else
+ bc=Max(y,Min(y+h-blocksize,MouseY()))
+ EndIf
+
+ If GetValue()<>old And callback<>Null
+ callback(Self)
+ EndIf
+ End Method
+
+ Method HandleDrag(mx:Int, my:Int)
+ Local old:Double=GetValue()
+
+ If horiz
+ bc=Max(x,Min(x+w-blocksize,bc+mx))
+ Else
+ bc=Max(y,Min(y+h-blocksize,bc+my))
+ EndIf
+
+ If GetValue()<>old And callback<>Null
+ callback(Self)
+ EndIf
+ End Method
+
+ Method Draw()
+ SetColor(64,64,64)
+ DrawRect(x,y,w,h)
+ If horiz
+ Draw3DBox(bc,y,blocksize,h,False,1)
+ Else
+ Draw3DBox(x,bc,w,blocksize,False,1)
+ EndIf
+ End Method
+End Type
+
+Rem
bbdoc: Handles the GUI.
EndRem
Type TGUIHandler
@@ -692,6 +1062,10 @@ Type TGUIHandler
Field m_focus:TWidget
Field m_over:TWidget
Field m_clicked:TWidget
+ Field m_dragging:Int
+ Field m_dragx:Int
+ Field m_dragy:Int
+ Field m_dragobj:TWidget
Rem
bbdoc: Create a GUI Handler.
@@ -706,13 +1080,17 @@ Type TGUIHandler
o.m_focus=Null
o.m_over=Null
o.m_clicked=Null
+ o.m_dragging=False
+ o.m_dragx=0
+ o.m_dragy=0
+ o.m_dragobj=Null
Return o
End Function
Rem
bbdoc: Register a widget.
- about: Widgets call this themselves.
+ about: Widgets in the library call this themselves when creating.
EndRem
Method Register(w:TWidget)
m_widgets.AddLast(w)
@@ -737,6 +1115,16 @@ Type TGUIHandler
End Method
Rem
+ bbdoc: Sets the displayed state of all widgets.
+ about: If @state is true then all widgets are enabled, otherwise all widgets are disabled
+ EndRem
+ Method SetDisplay(state:Int)
+ For Local w:TWidget=EachIn m_widgets
+ w.displayed=state
+ Next
+ End Method
+
+ Rem
bbdoc: Sets the keyboard focus to the supplied widget. Pass null for no focus.
EndRem
Method SetFocus(w:TWidget)
@@ -762,6 +1150,14 @@ Type TGUIHandler
End Method
Rem
+ bbdoc: Whether a widget is dragging
+ returns: True if a widget is consuming a mouse drag.
+ EndRem
+ Method IsDragging:Int()
+ Return m_dragging
+ End Method
+
+ Rem
bbdoc: Perform the event loop and pass any necessary events.
about: KeyHit(KEY_MOUSELEFT) and GetChar() are used to consume events for the interface.
EndRem
@@ -769,12 +1165,19 @@ Type TGUIHandler
Local x:Int=MouseX()
Local y:Int=MouseY()
Local b:Int=KeyHit(KEY_MOUSELEFT)>0
+ Local drag:Int=KeyDown(KEY_MOUSELEFT)
Local w:TWidget=LocateWidget(x,y)
For Local wid:TWidget=EachIn m_widgets
- If wid.enabled
- wid.Draw()
+ If wid.displayed
+ If wid.enabled
+ wid.Draw()
+ Else
+ SetAlpha(0.3)
+ wid.Draw()
+ SetAlpha(1)
+ EndIf
EndIf
Next
@@ -788,16 +1191,34 @@ Type TGUIHandler
EndIf
EndIf
- If w<>Null And w.enabled And b
+ If w<>Null And w.enabled And w.consumes&TWidget.HAS_CLICK=TWidget.HAS_CLICK And b And Not m_dragging
w.HandleClick()
m_clicked=w
EndIf
Local k:Int=GetChar()
- If k<>0 And m_focus<>Null And m_focus.enabled And m_focus.consumes
+ If k<>0 And m_focus<>Null And m_focus.enabled And m_focus.consumes&TWidget.HAS_KEY=TWidget.HAS_KEY
m_focus.HandleKey(k)
EndIf
+
+ If drag
+ If m_dragging
+ m_dragobj.HandleDrag(MouseX()-m_dragx,MouseY()-m_dragy)
+ m_dragx=MouseX()
+ m_dragy=MouseY()
+ Else
+ If w<>Null And w.consumes&TWidget.HAS_DRAG=TWidget.HAS_DRAG
+ m_dragging=True
+ m_dragx=MouseX()
+ m_dragy=MouseY()
+ m_dragobj=w
+ EndIf
+ EndIf
+ Else
+ m_dragging=False
+ m_dragobj=Null
+ EndIf
End Method
' Private method
@@ -976,6 +1397,117 @@ Function GUIMenu(title:String, options:String[], x:Int, y:Int, i:TImage=Null)
End Function
Rem
+bbdoc: Displays a basic file selector.
+returns: The selected file, or null for none.
+about: @title is the title. @file is the initially selected file, and f set to null then no file is selected and the current directory displayed.
+about: Set @save to true for a save dialog (the filename can be altered).
+about: If @i is not null then this image is drawn as a mouse cursor.
+EndRem
+Function GUIFileSelect:String(title:String, file:String, save:Int, i:TImage=Null)
+ FlushKeys()
+
+ Local oldpwd:String=CurrentDir()
+ Local dir:String
+ Local fn:String
+ Local sw:Int=GraphicsWidth()
+ Local sh:Int=GraphicsHeight()
+ Local fh:Int=TGUIFont.font.MaxHeight()
+ Local fw:Int=TGUIFont.font.MaxWidth()
+ Local rows:Int=(sh-fh*10)/fh
+
+ If file<>Null And file<>""
+ dir=ExtractDir(file)
+
+ If dir=""
+ dir=oldpwd
+ EndIf
+
+ If FileType(file)=FILETYPE_FILE
+ fn=StripDir(file)
+ Else
+ fn=""
+ EndIf
+ Else
+ dir=oldpwd
+ fn=""
+ EndIf
+
+ Local gui:TGUIHandler=TGUIHandler.Create()
+
+ TPanel.Create(gui,0,0,sw,sh)
+ TLabel.Create(gui,10,fh*0.5,title)
+
+ Local list:TTextList=TTextList.Create(gui,20,fh*2,sw-40,rows)
+ Local scroll:TScrollbar=TScrollbar.Create(gui,list.x+list.w+5,list.y,10,list.h)
+
+ Local fntext:TText
+
+ If save
+ fntext=TText.Create(gui,20,sh-fh*6,fn,(sw-40)/fw,TText.FILENAME)
+ Else
+ fntext=TText.Create(gui,20,sh-fh*6,fn,(sw-40)/fw,TText.READONLY)
+ EndIf
+
+ Local bw:Int=TGUIFont.font.MaxWidth()*9
+
+ Local cancel:TButton=TButton.Create(gui,sw-bw-20,sh-fh*3.5,bw,fh*2.5,"Cancel",Null)
+ Local ok:Tbutton=TButton.Create(gui,cancel.x-bw-10,cancel.y,bw,fh*2.5,"OK",Null)
+
+ Local last:TDirEntry=Null
+
+ ChangeDir(dir)
+ LoadDirEnts(list,scroll,rows)
+
+ Repeat
+ Cls
+
+ gui.EventLoop()
+
+ TGUIFont.font.Draw(CurrentDir(),list.x,list.y+list.h+3)
+
+ Local click:TWidget=gui.Clicked()
+
+ If click=ok
+ Local ret:String=CurrentDir()+"/"+fntext.text
+ ChangeDir(oldpwd)
+ FlushKeys()
+ Return ret
+ EndIf
+
+ If click=cancel Or KeyHit(KEY_ESCAPE)
+ ChangeDir(oldpwd)
+ FlushKeys()
+ Return Null
+ EndIf
+
+ If list.GetSelectedItem()<>last
+ last=TDirEntry(list.GetSelectedItem())
+
+ If last.is_dir
+ ChangeDir(last.filename)
+ LoadDirEnts(list,scroll,rows)
+ fntext.text=""
+ last=Null
+ Else
+ fntext.text=last.filename
+ EndIf
+ EndIf
+
+ ok.enabled=(fntext.text<>"")
+
+ list.SetTopRow(scroll.GetValue())
+
+ If i<>Null
+ SetColor(255,255,255)
+ DrawImage(i,MouseX(),MouseY())
+ EndIf
+
+ Flip
+ FlushMem
+ Forever
+End Function
+
+Rem
bbdoc: Handles a TGUIHandler as if it's a modal dialog.
returns: True if @ok is pressed, False if @cancel or the ESCAPE key is pressed. ESCAPE is only allowed if nothing has the text focus.
about: @gui is the GUI handler and widgets to display as a dialog., @ok is the clickable widget that OK's the dialog, @cancel the widget that cancels it.
@@ -1018,6 +1550,7 @@ Function GUIDialog(gui:TGUIHandler, ok:TWidget, cancel:TWidget, i:TImage=Null)
FlushMem
Wend
+ FlushKeys()
Return ok_pressed
End Function
@@ -1058,3 +1591,78 @@ Type TSplitText
Return o
End Function
EndType
+
+Type TDirEntry Extends TTextListItem
+ Field path:String
+ Field dir:String
+ Field filename:String
+ Field size:Int
+ Field is_dir:Int
+
+ Function Create:TDirEntry(path:String)
+ Local o:TDirEntry=New TDirEntry
+ o.path=path
+ o.dir=ExtractDir(path)
+ o.filename=StripDir(path)
+ o.is_dir=(FileType(path)=FILETYPE_DIR)
+ o.size=FileSize(path)
+ Return o
+ End Function
+
+ Method Compare:Int(o:Object)
+ Local d:TDirEntry=TDirEntry(o)
+
+ If d=Null
+ Return 0
+ EndIf
+
+ If is_dir=d.is_dir
+ Return filename.Compare(d.filename)
+ Else
+ If is_dir
+ Return -1
+ Else
+ Return 1
+ EndIf
+ EndIf
+
+ Return 0
+ End Method
+
+ Method Columns:Int()
+ Return 2
+ End Method
+
+ Method ColumnOffset:Int(i:Int)
+ If i=0
+ Return 0
+ Else
+ Return GraphicsWidth()-TGUIFont.font.MaxWidth()*20
+ EndIf
+ End Method
+
+ Method ColumnData:String(i:Int)
+ If i=0
+ Return filename
+ Else
+ If is_dir
+ Return "DIR"
+ Else
+ Return size+" bytes"
+ EndIf
+ EndIf
+ End Method
+End Type
+
+Function LoadDirEnts(list:TTextList, scroll:TScrollbar, rows:Int)
+ Local d:TList=CreateList()
+
+ For Local s:String=EachIn LoadDir(CurrentDir(),False)
+ d.AddLast(TDirEntry.Create(CurrentDir()+"/"+s))
+ Next
+
+ d.Sort()
+
+ list.SetOptions(d.ToArray())
+ scroll.SetBar(0,Max(1,d.Count()-rows/2),1)
+End Function