Module noddybox.simplegui ModuleInfo "Framework: (Very) Simple GUI" ModuleInfo "Copyright: Public Domain" ModuleInfo "Author: Ian Cowburn" ModuleInfo "Version: $Revision$" ' $Id$ Strict Import brl.Max2D Import brl.Basic Import noddybox.bitmapfont Type TGUIFont Global font:TBitmapFont End Type Type TWidget Abstract Field enabled:Int Field text:String Field x:Int Field y:Int Field w:Int Field h:Int Field owner:TGUIHandler Field callback(w:TWidget) Field mouse_over:Int Method HandleKey(k:Int) End Method Method MouseEnter() mouse_over=True End Method Method MouseLeave() mouse_over=False End Method Method HandleClick() End Method Method Draw() Abstract Function DrawBox(x:Int, y:Int, w:Int, h:Int) DrawLine(x,y,x+w-1,y) DrawLine(x+w-1,y,x+w-1,y+h-1) DrawLine(x+w-1,y+h-1,x,y+h-1) DrawLine(x,y+h-1,x,y) End Function Function Draw3DBox(x:Int, y:Int, w:Int, h:Int, invert:Int, size:Int=2) Local f:Int SetColor(200,200,200) DrawRect(x,y,w,h) If invert SetColor(170,170,170) Else SetColor(230,230,230) EndIf For f=0 Until size DrawLine(x+f,y+f,x+w-1-f,y+f) DrawLine(x+w-1-f,y+f,x+w-1-f,y+h-1-f) Next If invert SetColor(230,230,230) Else SetColor(170,170,170) EndIf For f=0 Until size DrawLine(x+w-1-f,y+h-1-f,x+f,y+h-1-f) DrawLine(x+f,y+h-1-f,x+f,y+f) Next End Function End Type Type TLabel Extends TWidget Function Create:TLabel(gui:TGUIHandler,x:Int, y:Int, text:String) Local o:TLabel=New TLabel o.enabled=True o.x=x o.y=y o.w=TGUIFont.font.TextWidth(text)+2 o.h=TGUIFont.font.MaxHeight()+1 o.text=text gui.Register(o) Return o End Function Method Draw() TGUIFont.font.Draw(text,x+1,y+1) End Method End Type Type TText Extends TWidget Field maxlen:Int Function Create:TText(gui:TGUIHandler,x:Int, y:Int, text:String, maxlen:Int, callback(w:TWidget)=Null) Local o:TText=New TText o.enabled=True o.x=x o.y=y o.maxlen=maxlen o.w=TGUIFont.font.MaxWidth()*(maxlen+1)+2 o.h=TGUIFont.font.MaxHeight()+2 o.text=text o.callback=callback gui.Register(o) Return o End Function Method HandleClick() owner.SetFocus(Self) End Method Method HandleKey(k:Int) If k=8 If text.length>0 text=text[0..text.length-1] EndIf Else If k=13 If callback<>Null callback(Self) owner.SetFocus(Null) EndIf Else If k>31 And k<127 And text.lengthNull callback(Self) EndIf End Method Method Draw() If (mouse_over) SetColor(255,255,255) Else SetColor(200,200,200) EndIf DrawBox(x,y,TGUIFont.font.MaxHeight(),TGUIFont.font.MaxHeight()) If checked SetColor(255,100,100) DrawRect(x+1,y+1,TGUIFont.font.MaxHeight()-2,TGUIFont.font.MaxHeight()-2) EndIf TGUIFont.font.Draw(" "+text,x+2+TGUIFont.font.MaxHeight(),y+1) End Method End Type Type TButton Extends TWidget Field ox:Int Field oy:Int Function Create:TButton(gui:TGUIHandler, x:Int, y:Int, w:Int, h:Int, text:String, callback(w:TWidget)) Local o:TButton=New TButton o.enabled=True o.x=x o.y=y o.w=w o.h=h o.text=text o.ox=x+w/2-TGUIFont.font.TextWidth(text)/2 o.oy=y+h/2-TGUIFont.font.TextHeight(text)/2 o.callback=callback gui.Register(o) Return o End Function Method HandleClick() If callback<>Null callback(Self) EndIf End Method Method Draw() If (mouse_over) SetColor(255,255,255) DrawBox(x,y,w,h) EndIf Draw3DBox(x+1,y+1,w-2,h-2,False,2) TGUIFont.font.Draw(text,ox,oy) End Method End Type Type TGUIHandler ' These are private ' Field m_widgets:TList Field m_focus:TWidget Field m_over:TWidget Field m_clicked:TWidget ' Creates a new GUI handler ' Function Create:TGUIHandler() Local o:TGUIHandler o=New TGUIHandler o.m_widgets=CreateList() o.m_focus=Null o.m_over=Null o.m_clicked=Null Return o End Function ' Register a widget ' Method Register(w:TWidget) m_widgets.AddLast(w) w.owner=Self End Method ' Clear widgets ' Method Clear() m_widgets.Clear() End Method ' Set the keyboard focus (null for none) ' Method SetFocus(w:TWidget) m_focus=w End Method ' Get the keyboard focus (null for none) ' Method GetFocus:TWidget() Return m_focus End Method ' Gets the last clicked widget ' Method Clicked:TWidget() Local last:TWidget=m_clicked m_clicked=Null Return last End Method ' Perform a loop and any necessary events ' Method EventLoop() Local x:Int=MouseX() Local y:Int=MouseY() Local b:Int=KeyHit(KEY_MOUSELEFT)>0 Local w:TWidget=LocateWidget(x,y) For Local w:TWidget=EachIn m_widgets If w.enabled w.Draw() EndIf Next If w<>m_over If m_over<>Null m_over.MouseLeave() EndIf m_over=w If m_over<>Null m_over.MouseEnter() EndIf EndIf If w<>Null And w.enabled And b w.HandleClick() m_clicked=w EndIf Local k:Int=GetChar() If k<>0 And m_focus<>Null And m_focus.enabled m_focus.HandleKey(k) EndIf End Method ' Private method ' Method LocateWidget:TWidget(x:Int,y:Int) For Local w:TWidget=EachIn m_widgets If x>=w.x And y>=w.y And xbutton Cls DrawImage(back,0,0) TWidget.Draw3DBox(x,y,w,h,False,2) gui.EventLoop() click=gui.Clicked() Flip FlushMem Wend End Function Function GUIYesNo:Int(s:String) Local back:TImage=CreateImage(GraphicsWidth(),GraphicsHeight(),1,0) GrabImage(back,0,0) Local w:Int=Max(TGUIFont.font.TextWidth(s)+10,GraphicsWidth()/4) Local h:Int=TGUIFont.font.TextHeight(s)*7 Local x:Int=GraphicsWidth()/2-w/2 Local y=GraphicsHeight()/2-h/2 Local by=y+TGUIFont.font.TextHeight(s)*2 Local gui:TGUIHandler=TGUIHandler.Create() Local label:TLabel=TLabel.Create(gui,x+5,y+5,s) Local yes:TButton=TButton.Create(gui,x+5,by,w-10,TGUIFont.font.TextHeight(s)+10,"Yes",Null) Local no:TButton=TButton.Create(gui,x+5,by+yes.h+2,w-10,TGUIFont.font.TextHeight(s)+10,"No",Null) Local click:TWidget=Null While click=Null Cls DrawImage(back,0,0) TWidget.Draw3DBox(x,y,w,h,False,2) gui.EventLoop() click=gui.Clicked() Flip FlushMem Wend Return click=yes End Function Function GUIMenu(title:String, options:String[],x,y) Local f:Int Local back:TImage=CreateImage(GraphicsWidth(),GraphicsHeight(),1,0) GrabImage(back,0,0) Local st:Int=TGUIFont.font.MaxHeight()*2 Local h:Int=TGUIFont.font.MaxHeight()*3 Local w:Int=TGUIFont.font.TextWidth(title)+30 For f=0 Until options.length w=Max(w,TGUIFont.font.TextWidth(options[f])+30) h:+st Next Local gui:TGUIHandler=TGUIHandler.Create() Local label:TLabel=TLabel.Create(gui,x+5,y+2,title) Local button:TButton[]=New TButton[options.length] For f=0 Until options.length button[f]=TButton.Create(gui,x+5,y+TGUIFont.font.MaxHeight()*2+f*st,w-10,st-2,options[f],Null) Next Local click:TWidget=Null While click=Null And KeyHit(KEY_MOUSERIGHT)=0 Cls DrawImage(back,0,0) TWidget.Draw3DBox(x,y,w,h,False,2) gui.EventLoop() click=gui.Clicked() Flip FlushMem Wend For f=0 Until options.length If button[f]=click Return f EndIf Next Return -1 End Function