Immediate GUI

Monkey Forums/Monkey Code/Immediate GUI

Dima(Posted 2011) [#1]
Hey guys,

I want to share a technique for a simple gui system that is; minimal to implement, easy to understand, and can be easily extended. The logic behind this system is that defining, drawing, and updating is done with a single method call. At the very minimal this system does not contain any internal state, but this can be extended for the use of keyboard controls or tabbing between controls for example (out of scope for this sample).

This is a really quick way of getting a gui on the screen, and if properly developed can be used as a full blown system. There are some things to watch though; stateless means the system has no idea about anything that's happening with other controls or even itself, for example even the positions are passed on the fly.

This sample isn't pretty to look at; just simple rects and built in fonts, and it's only a button, but it demonstrates the methodology behind this system. Any other component can be implemented, some will require adding minimal state. The mouse logic code is inside rendering routine as well to keep it synchronized with the gui.

Internet has more details on Immediate Mode GUIs, but here are some links anyway:
http://sol.gfxile.net/imgui/
http://mollyrocket.com/861

' Immediate Mode GUI Sample

' the sliding button is unnecessary addition but shows how state is tracked outside the controls.

Import mojo

Class ImGuiTest Extends App

	' for tracking mouse state inside OnRender()
	' mUp only triggers once per mouse release
	Field mUp?, mDown?
	
	' for the scrolling button
	Field bx%
	Field bw% = 100
	
	Method OnCreate()
		SetUpdateRate(60)
	End

	Method OnUpdate()		
		' scroll the button sideways
		bx += 5
		If bx > DeviceWidth() bx = -bw
	End
 
	Method OnRender()
		Cls

		If MouseDown()
			mDown = True
		Else
			If mDown
				mUp = True			
				mDown = False 
			Else
				mUp = False 
			End
		End
		
		If DoButton("Button 1", 100, 100, bw, 25)
			Print("Button 1 clicked")
		End 
		If DoButton("Button 2", 100, 150, bw, 25)
			Print("Button 2 clicked")
		End 
		If DoButton("Do Not Click", bx, 300, bw, 25)
			Print("NO DON'T CLICK IT!")
		End 
	End

	Method DoButton?(cap$, x#, y#, w#, h#)
		' if mouse is hovering over
		If MouseX() > x And MouseX() < x+w And MouseY() > y And MouseY() < y+h
			SetColor(0,65,0)
			If mUp
				' mouse up means button click
				Return True
			Elseif MouseDown()
				' mouse is clicked but not released yet
				SetColor(33,65,73)
			End
		Else
			' mouse is not over the button
			SetColor(0,35,0)
		End
		
		' display button
		DrawRect(x, y, w, h)
		SetColor(255,255,255)
		DrawText(cap, x+5, y+5)
		
		Return False 
	End
	
End

Function Main()
	New ImGuiTest
End





Michael(Posted 2012) [#2]
Thanks alot for this - it's helpful.