Code archives/Miscellaneous/GUI Base Code
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
You can use this code as a base for creating a GUI system for any kind of game/app. The code below is only the code listing from the major file and as such you will need to download This(~59kb) for all the code. Enjoy! | |||||
SuperStrict Rem Imports EndRem Import "rect.bmx" Import BRL.LinkedList Import BRL.Max2D Rem bbdoc: The current handle of the active gadget EndRem Global GUIactiveGadget:GUI_TGadget Rem bbdoc: The current gadget that the mouse is over EndRem Global GUIOverGadget:GUI_TGadget Global GUIMouseState%[4] Global GUIKeyState%[227] Global GUIKeyStack:TList = CreateList() Rem Just a helper type EndRem Type GUI_TKey Field key% End Type Rem bbdoc: Base type for all gadgets endrem Type GUI_TGadget Global gadgetList:TList = CreateList() ' List of all gadgets Field name$ ' Name of the gadget Field parent:GUI_TGadget ' Parent of the gadget Field x%, y%, w%, h% ' Gadgets 'rect' Field lx%, ly%, lw%, lh% ' Gadgets local 'rect' Field z% ' z~ position of the gadget Field renderRect:GUI_TRect ' The render rect for this gadget Field r%, g%, b%, a# = 1 ' Red, Green, Blue & alpha of the gadget Field ChildList:TList = CreateList() ' List of children Field ClientX% ' If a gadget is created and the parent is this, X is offseted by this Field clientY% ' If a gadget is created and the parent is this, Y is offseted by this Field ClientW% ' Client area with Field ClientH% ' Client area height Field disabled@ ' Is this gadget disabled Field hidden@ ' Is this gadget hidden Field active@ ' Is this gadget the active one Field OnHide() ' Call this function on hidding Field OnShow() ' Call this function on showing Field OnMouseHit(_button%) ' Call this function if the mouse is hit Field OnMouseClicked(_button%) ' Call this function if a mouse button is clicked Field OnMouseDown(_button%) ' Call this function if a mouse button is down Field OnMouseOver(_mouseX%, _mouseY%) ' Call this function if the mouse is over Field OnMouseMove(_mouseX%, _mouseY%) ' Call this function if the mouse is moving on gadget Field OnMouseEnter(_mouseX%, _mouseY%) ' Call this function when mouse enters gadget Field OnMouseLeave(_mouseX%, _mouseY%) ' Call this function when the mouse leaves the gadget Field OnKeyHit(_key%) ' Call this function when a key is hit and gadget is active Field OnKeyDown(_key%) ' Call this function when a key is down Field OnKeyPressed(_key%) ' Call this function when a key is released Field OnFocusLoss() ' Call this function upon loss of focus i.e. no longer active gadget Field OnFocusGain() ' Call this function upon gain Field gadgetMouseState@[4] ' The state of mouse buttons Field gadgetKeyState@[227] ' The state of the keys Field gadgetMouseMoved@ ' True if the mouse was moved over the gadget Field gadgetMouseOver@ ' True if the mouse is over the gadget Field gadgetMouseEnter@ ' True if the mouse entered the gadget Field gadgetMouseLeave@ ' True if the mouse leaves the gadget Field gadgetAlwaysOnTop@ ' Is the gadget always on top Field gadgetAlwaysOnBottom@ ' Is the gadget always on bottom Field gadgetMouseMoveX% ' Amount the gadget mouse x has moved Field gadgetMouseMoveY% ' Amount the gadget mouse y has moved Field gadgetLocalMouseX% ' Local mouse x position Field gadgetLocalMouseY% ' Local mouse y position Const GADGET_KEYHIT% = %0001 Const GADGET_KEYDOWN% = %0010 Const GADGET_KEYPRESSED% = %0100 Const GADGET_KEYUP% = %1000 Rem bbdoc: Check if a key was hit endrem Method IsKeyHit@(_key%) If gadgetKeyState[_key] = GADGET_KEYHIT Then Return True End Method Rem bbdoc: Check if a key was pressed endrem Method IsKeyPressed@(_key%) If gadgetKeyState[_key] = GADGET_KEYPRESSED Then Return True End Method Rem bbdoc: Check if a key is down endrem Method IsKeyDown@(_key%) If gadgetKeyState[_key] = GADGET_KEYDOWN Then Return True End Method Rem bbdoc: Check if a key is up endrem Method IsKeyUp@(_key%) If gadgetKeyState[_key] = GADGET_KEYUP Then Return True End Method Rem bbdoc: Check if mouse button was hit endrem Method IsMouseHit@(_button%) If gadgetMouseState[_button] = GADGET_KEYHIT Then Return True End Method Rem bbdoc: Check if a mouse button is down endrem Method IsMouseDown@(_button%) If gadgetMouseState[_button] = GADGET_KEYDOWN Then Return True End Method Rem bbdoc: Check if a mouse button was pressed endrem Method IsMousePressed@(_button%) If gadgetMouseState[_button] = GADGET_KEYPRESSED Then Return True End Method Rem bbdoc: Check if a mouse button is up endrem Method IsMouseUp@(_button%) If gadgetMouseState[_button] = GADGET_KEYUP Then Return True End Method Rem bbdoc: Check if the mouse was moved returns: True if mouse was moved EndRem Method IsMouseMoved@() Return gadgetMouseMoved End Method Rem bbdoc: Check if the mouse entered the gadget returns: True if the mouse entered the gadget EndRem Method IsMouseEntering@() Return gadgetMouseEnter End Method Rem bbdoc: Check if the mouse has left the gadget returns: True if it is ?< EndRem Method IsMouseLeaving@() Return gadgetMouseLeave End Method Rem bbdoc: Get the amount the mouse was moved returns: The amount the mouse was move (x) EndRem Method GetGadgetMouseXSpeed%() Global lastX:Int = MouseX() Local result:Int = MouseX() - lastX lastX = MouseX() Return result End Method Rem bbdoc: Get the amount the mouse was moved returns: The amount the mouse was move (y) EndRem Method GetGadgetMouseYSpeed%() Global lastY:Int = MouseY() Local result:Int = MouseY() - lastY lastY = MouseY() Return result End Method Rem bbdoc: Move the gadget to a new position EndRem Method Move(_x%, _y%) x = _x y = _y For Local kid:GUI_TGadget = EachIn ChildList kid.Move(_x + kid.lx, _y + kid.ly) Next End Method Rem bbdoc: Is mouse over the gadget endrem Method IsMouseOver@() If IsInGadget(MouseX(), MouseY()) Then Return True End Method Rem bbdoc: Update the gadgets local rect about: Call this function after you have moved gadgets about endrem Method UpdateLocalRect() lx = x ly = y lw = w lh = h If parent Then lx:- parent.x ly:- parent.y EndIf End Method Rem bbdoc: Set if the gadget will always be on top EndRem Method SetAlwaysOnTop(_to@) gadgetAlwaysOnTop = _to If _to = True Then gadgetAlwaysOnBottom = False End Method Rem bbdoc: Set if the gadget will always be on bottom EndRem Method SetAlwaysOnbottom(_to@) gadgetAlwaysOnbottom = _to If _to = True Then gadgetAlwaysOnTop = False End Method Rem bbdoc: Render the gadget (debug render here!!!) EndRem Method Render() Local lastBlend% = GetBlend() Local vx%, vy%, vw%, vh% GetViewport(vx, vy, vw, vh) ' Set this render rect to x,y,w,h (duh!) renderRect.Set(x, y, w, h) If parent Then renderRect = parent.renderRect.InterRect(renderRect) EndIf SetViewport renderRect.x, renderRect.y, renderRect.w, renderRect.h SetBlend ALPHABLEND SetColor 0, 0, 0 DrawRect x, y, w, 1 DrawRect x, y, 1, h DrawRect (x + w) - 1, y, 1, h DrawRect x, (y + h) - 1, w, 1 SetColor r, g, b SetAlpha a DrawRect x + 1, y + 1, w - 2, h - 2 SetColor 0, 0, 0 DrawText name, x + 3, y + 3 DrawText z, x + w - 6 - 20, y + h - 6 - 12 SetColor 255, 255, 255 SetAlpha 1 SetViewport(vx, vy, vw, vh) End Method Rem bbdoc: Update the gadget endrem Method Update() If IsInGadget(MouseX(), MouseY()) Then GUIOverGadget = Self ' Set some globals up Global _lastMouseX% = MouseX(), _lastMouseY% = MouseY() Global mouseState%, lastMouseDown% Global keyState%, lastKeyDown%, lastKeyDownStack:TList = CreateList() ' Clear some flags gadgetMouseEnter = False gadgetMouseLeave = False gadgetMouseOver = False gadgetMouseMoved = False If Not IsInGadget(_lastMouseX, _lastMouseY) Then If IsInGadget(MouseX(), MouseY()) Then If OnMouseEnter Then OnMouseEnter(MouseX(), MouseY()) keyState = 0 mouseState = 0 gadgetMouseEnter = True EndIf End If If IsInGadget(MouseX(), MouseY()) Then ' Now that we know the mouse if in the gadget we can call the mouse over function If OnMouseOver Then OnMouseOver(MouseX() - x, MouseY() - y) gadgetMouseOver = True gadgetLocalMouseX = (MouseX() - x) gadgetLocalMouseY = (MouseY() - y) If GetGadgetMouseXSpeed() <> 0 Or GetGadgetMouseYSpeed() <> 0 Then gadgetMouseMoved = True If OnMouseMove Then OnMouseMove(MouseX(), MouseY()) _lastMouseX = MouseX() _lastMouseY = MouseY() EndIf ' Check if a key was pressed For Local key% = 8 To 226 gadgetKeyState[key] = GADGET_KEYUP Local akey:GUI_TKey = New GUI_TKey akey.key = key ' Check if a key was hit and call function If GUI_InStack(key, GUIKeyStack) = 1 Then If OnKeyHit Then OnKeyHit(key) gadgetKeyState[key] = GADGET_KEYHIT EndIf ' Check if a key is down and call function If KeyDown(key) Then If OnKeyDown Then OnKeyDown(key) keyState = 2 If Not GUI_InStack(key, lastKeyDownStack) Then lastKeyDownStack.AddLast akey If gadgetKeyState[key] <> GADGET_KEYHIT Then gadgetKeyState[key] = GADGET_KEYDOWN EndIf ' Check is a key was 'pressed' and call function If Not KeyDown(key) And keyState = 2 And GUI_InStack(key, lastKeyDownStack) Then If OnKeyPressed Then OnKeyPressed(key) keyState = 0 GUI_RemoveFromStack(key, lastKeyDownStack) gadgetKeyState[key] = GADGET_KEYPRESSED EndIf Next gadgetMouseState[1] = GADGET_KEYUP gadgetMouseState[2] = GADGET_KEYUP gadgetMouseState[3] = GADGET_KEYUP ' Check for mouse hits and call functions If GUIMouseState[1] = 1 Then If OnMouseHit Then OnMouseHit(1) Activate() gadgetMouseState[1] = GADGET_KEYHIT EndIf If GUIMouseState[2] = 1 Then If OnMouseHit Then OnMouseHit(2) Activate() gadgetMouseState[2] = GADGET_KEYHIT EndIf If GUIMouseState[3] = 1 Then If OnMouseHit Then OnMouseHit(3) Activate() gadgetMouseState[3] = GADGET_KEYHIT EndIf ' Check mouse down, call functions and set state If MouseDown(1) Then If OnMouseDown Then OnMouseDown(1) mouseState = 2 lastMouseDown = 1 If gadgetMouseState[1] <> GADGET_KEYHIT Then gadgetMouseState[1] = GADGET_KEYDOWN ElseIf MouseDown(2) If OnMouseDown Then OnMouseDown(2) mouseState = 2 lastMouseDown = 2 If gadgetMouseState[2] <> GADGET_KEYHIT Then gadgetMouseState[2] = GADGET_KEYDOWN ElseIf MouseDown(3) If OnMouseDown Then OnMouseDown(3) mouseState = 2 lastMouseDown = 3 If gadgetMouseState[3] <> GADGET_KEYHIT Then gadgetMouseState[3] = GADGET_KEYDOWN EndIf ' Check if a mouse button is released (clicked) If Not MouseDown(1) And mouseState = 2 And lastMouseDown = 1 Then If OnMouseClicked Then OnMouseClicked(1) mouseState = 0 gadgetMouseState[1] = GADGET_KEYPRESSED ElseIf Not MouseDown(2) And mouseState = 2 And lastMouseDown = 2 If OnMouseClicked Then OnMouseClicked(2) mouseState = 0 gadgetMouseState[2] = GADGET_KEYPRESSED ElseIf Not MouseDown(3) And mouseState = 2 And lastMouseDown = 3 If OnMouseClicked Then OnMouseClicked(3) mouseState = 0 gadgetMouseState[3] = GADGET_KEYPRESSED EndIf Else If IsInGadget(_lastMouseX, _lastMouseY) Then gadgetMouseLeave = True If onMouseLeave Then OnMouseLeave(MouseX(), MouseY()) lastMouseDown = -1 gadgetMouseState[1] = GADGET_KEYUP gadgetMouseState[2] = GADGET_KEYUP gadgetMouseState[3] = GADGET_KEYUP EndIf EndIf End Method Rem bbdoc: Check if a position is in the gadget returns: True if x AND y is in the gadget (byte) endrem Method IsInGadget@(_x%, _y%) If hidden Then Return False If disabled Then Return False ' See if we'er in any other gadgets For Local gadget:GUI_TGadget = EachIn gadgetList If gadget <> Self Then If gadget.z > z Then If gadget.IsInGadget(_x, _y) Then Return False EndIf EndIf Next If _x <= x + w And _x => x And _y <= y + h And _y => y Then Return True Return False End Method Rem bbdoc: Disable this gadget and all its kids endrem Method Disable() If disabled Then Return disabled = True If ChildList Then For Local gadget:GUI_TGadget = EachIn ChildList gadget.Disable() Next EndIf End Method Rem bbdoc: Enable this gadget and all its kids endrem Method Enable() If disabled = False Then Return If disabled Then If parent.disabled Then Return disabled = False If ChildList Then For Local gadget:GUI_TGadget = EachIn ChildList gadget.Enable() Next EndIf End Method Rem bbdoc: Hides the gadget endrem Method Hide() If hidden Then Return If OnHide Then OnHide() hidden = True If ChildList Then For Local gadget:GUI_TGadget = EachIn ChildList gadget.Hide() Next EndIf End Method Rem bbdoc: Show a gadget endrem Method Show() If hidden = False Then Return If parent Then If parent.hidden Then Return If OnShow Then OnShow() hidden = False If ChildList Then For Local gadget:GUI_TGadget = EachIn ChildList gadget.Hide() Next EndIf End Method Rem bbdoc: Activate this gadget endrem Method Activate() If Not active Then active = True GUIactiveGadget = Self If OnFocusGain Then OnFocusGain() ' Unactivate all other gadgets For Local gadget:GUI_TGadget = EachIn gadgetList If gadget <> Self Then gadget.active = False If gadget.OnFocusLoss Then gadget.OnFocusLoss() EndIf Next EndIf End Method Rem bbdoc: Create a *very* basic gadget endrem Function Create:GUI_TGadget(_name$, _x%, _y%, _w%, _h%, _parent:GUI_TGadget = Null) Local gadget:GUI_TGadget = New GUI_TGadget gadget.name = _name gadget.x = _x gadget.y = _y gadget.w = _w gadget.h = _h gadget.UpdateLocalRect() gadget.ClientX = 1 gadget.clientY = 1 gadget.ClientW = _w - 2 gadget.ClientH = _h - 2 gadget.r = 255 gadget.g = 255 gadget.b = 255 gadget.a = 1.0 gadget.renderRect = New GUI_TRect gadget.renderRect.x = _x gadget.renderRect.y = _y gadget.renderRect.w = _w gadget.renderRect.h = _h If _parent Then gadget.SetParent(_parent) gadget.x:+ _parent.ClientX + _parent.x gadget.y:+ _parent.clientY + _parent.y EndIf gadget.BringToTop() gadget.Activate() gadgetList.AddLast(gadget) Return gadget End Function Rem bbdoc: Setup the gadget EndRem Method Setup(_name$, _x%, _y%, _w%, _h%, _parent:GUI_TGadget = Null) name = _name x = _x y = _y w = _w h = _h UpdateLocalRect() ClientX = 1 clientY = 1 ClientW = _w - 2 ClientH = _h - 2 r = 255 g = 255 b = 255 a = 1.0 renderRect = New GUI_TRect renderRect.x = _x renderRect.y = _y renderRect.w = _w renderRect.h = _h If _parent Then SetParent(_parent) x:+ _parent.ClientX + _parent.x y:+ _parent.clientY + _parent.y EndIf BringToTop() Activate() If Not gadgetList.Contains(Self) Then gadgetList.AddLast(Self) End Method Rem bbdoc: Set the parent of this gadget EndRem Method SetParent(_gadget:GUI_TGadget) ' If it already has a parent the remove it from the child list If parent Then parent.ChildList.Remove(Self) EndIf ' Make _gadget the new parent and add it to the list parent = _gadget If parent Then If Not parent.ChildList Then parent.ChildList = CreateList() parent.ChildList.AddLast(Self) z = parent.z + 1 EndIf End Method Rem bbdoc: Bring this gadget to the top and re-order kids endrem Method BringToTop() If gadgetAlwaysOnBottom Then z = 0; Return ' If this gadget has a parent then bring the parent to top instead If parent Then parent.BringToTop() EndIf ' Set this z to the highest z... z = gadgetList.count() ' ... and then set all other gadgets z - 1 For Local gadget:GUI_TGadget = EachIn gadgetList If gadget <> Self Then If gadget.z > 0 Then gadget.z:- 1 If gadget.gadgetAlwaysOnTop Then gadget.BringToTop() EndIf Next OrderChildren() End Method Rem bbdoc: Re-order the gadgets children endrem Method OrderChildren() If ChildList = Null Then Return For Local kid:GUI_TGadget = EachIn ChildList kid.z = z kid.OrderChildren() Next End Method Rem bbdoc: Free the gadget EndRem Method Free() For Local kid:GUI_TGadget = EachIn childList kid.free() Next gadgetList.Sort() gadgetList.Remove(Self) OnMouseHit = Null OnMouseClicked = Null OnMouseDown = Null OnMouseOver = Null OnMouseMove = Null OnMouseEnter = Null OnMouseLeave = Null OnKeyHit = Null OnKeyDown = Null OnKeyPressed = Null OnFocusLoss = Null End Method Rem Override the new method EndRem Method New() BringToTop() End Method Rem Override the compare method endrem Method Compare%(other:Object) If other = Self Then Return False Local otherGadget:GUI_TGadget = GUI_TGadget(other) Return z - otherGadget.z 'If z > otherGadget.z Then Return True 'Return False End Method Rem Override the delete method endrem Method Delete() For Local kid:GUI_TGadget = EachIn childList kid.free() Next gadgetList.Sort() gadgetList.Remove(Self) OnMouseHit = Null OnMouseClicked = Null OnMouseDown = Null OnMouseOver = Null OnMouseMove = Null OnMouseEnter = Null OnMouseLeave = Null OnKeyHit = Null OnKeyDown = Null OnKeyPressed = Null OnFocusLoss = Null End Method Rem Override the ToString method EndRem Method ToString$() Local rString$ = "Ref = " + Super.ToString() + "; x = " + x + "; y = " + y + "; w = " + w + "; h = " + h + "; z = " + z If parent Then rString:+ "~r~n Has Parent {" + parent.ToString() + "}" Return rString End Method End Type Rem bbdoc: Render all the gadgets endrem Function GUI_Render() GUI_TGadget.gadgetList.Sort() For Local gadget:GUI_TGadget = EachIn GUI_TGadget.gadgetList If Not gadget.hidden Then gadget.Render() Next End Function Rem bbdoc: Update all the gadgets endrem Function GUI_Update() For Local i% = 1 To 3 GUIMouseState[i] = -1 If MouseHit(i) Then GUIMouseState[i] = 1 Next GUIKeyStack.Clear() For Local i% = 1 To 226 GUIKeyState[i] = -1 If KeyHit(i) Then GUIKeyState[i] = 1 If Not GUI_InStack(i, GUIKeyStack) Then Local key:GUI_TKey = New GUI_TKey key.key = i GUIKeyStack.AddLast key EndIf EndIf Next For Local gadget:GUI_TGadget = EachIn GUI_TGadget.gadgetList If gadget.hidden = False Or gadget.disabled = False Then gadget.Update() Next If GUIOverGadget And GUIMouseState[1] = 1 Then GUIOverGadget.BringToTop() End Function Rem bbdoc: Check if a key is in the stack returns: True on success (byte) endrem Function GUI_InStack@(_key%, _stack:TList) For Local key:GUI_TKey = EachIn _stack If key.key = _key Then Return True Next Return False End Function Rem bbdoc: Remove a key from a stack endrem Function GUI_RemoveFromStack(_key%, _stack:TList) For Local key:GUI_TKey = EachIn _stack If key.key = _key Then _stack.Remove(key) Return EndIf Next End Function |
Comments
None.
Code Archives Forum