[bb] Simple buttons by Pongo [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : Simple buttons
Author : Pongo
Posted : 1+ years ago

Description : This code will let you create buttons purely from code or load an image button and respond to button presses. This is merely set up as a very simple way to make these without resorting to a GUI lib.

Code :
Code: blitzbasic
Graphics 640,480,0,2
SetBuffer BackBuffer()

Global mx,my,info$
Global buttonheld,ID_clicked

Type button
	Field image$	;image containing button graphics
	Field x				;x position of button
	Field y				;y pos of button
	Field width		;width of button
	Field height		;height of button
	Field id			;so we know which button has been pressed
	Field state		;mouse over/up/down
End Type

; create text button examples
;Create a button like this: CreateTextButton.button (Label$,	x,y,	width,height,	id,	centered = False)
b1.button = CreateTextButton ("Test A",		50,50,	100,20,	 1,	0)
b2.button = CreateTextButton ("Test B",	50,80,	100,20,	 2,	0)
;if you use the centered option, the button will x position will be overidden and the button will center on the screen vertical axis
centered.button = CreateTextButton ("Centered long type",50,80,150,20, 3,1)

;##	Create an image button like this:  CreateImageButton.button (image$,x,y,id,centered = False)
;##	buttonimage = LoadAnimImage ("buttontest1.png",128,32,0,3)
;##	b.button = CreateImageButton (buttonimage,	50,250,5)

; create image button example. You will need to supply your own image with 3 frames,... normal, hit and rollover)
;Create an image button like this:  CreateImageButton.button (image,x,y,id,centered = False)


;b.button = CreateImageButton (LoadAnimImage ("buttontest1.png",128,32,0,3),	50,250,	5)


While Not KeyHit(1)
	mx = MouseX () : my = MouseY() ; grab the mouse position at the top of the loop

	updatebuttons() ; check rollover state and draw buttons to screen. Call this every loop.
	buttonaction() ;this will execute the results of any button presses.

	Text 50,420,Info$

	If KeyDown(57)
		;draw a cursor crosshair on the screen with the mouse coords
		Line mx,0,mx,GraphicsHeight() : Line 0,my,GraphicsWidth(),my ; draw crosshair on screen
		Text 0,0,mx + "," + my
	EndIf 

	Flip
	Cls
Wend
End

Function CreateTextButton.button (Label$,x,y,width,height,id,centered = False)
	b.button = New button

	bimage = CreateImage(width,height,3)

	;normal state of button
	SetBuffer ImageBuffer(bimage,0)
	Color 140,140,140
	Rect 0,0,width,height,1 ;fill
	Color 0,255,0
	Rect 0,0,width,height,0 ;outline
	Color 255,255,255
	Text width*.5,height*.5,label$,1,1

	;hit state of button
	SetBuffer ImageBuffer(bimage,1)
	Color 220,220,220
	Rect 0,0,width,height,1 ;fill
	Color 255,0,0
	Rect 0,0,width,height,0 ;outline
	Color 0,0,0
	Text width*.5,height*.5,label$,1,1

	;Rollover state of button
	SetBuffer ImageBuffer(bimage,2)
	Color 180,180,180
	Rect 0,0,width,height,1 ;fill
	Color 0,255,0
	Rect 0,0,width,height,0 ;outline
	Color 255,255,255
	Text width*.5,height*.5,label$,1,1

	SetBuffer BackBuffer()

	bx = x
	by = y
	bwidth = ImageWidth(bimage)
	bheight = ImageHeight(bimage)
	bid = id
	bstate = 0

	If centered Then bx = (GraphicsWidth()*.5) - (bwidth*.5) ;center on screen vertically

	Return b
End Function

Function CreateImageButton.button (image,x,y,id,centered = False)
	b.button = New button
	bimage = image
	MaskImage bimage,255,0,255 ; mask out pink color
	bx = x
	by = y
	bwidth = ImageWidth(image)
	bheight = ImageHeight(image)
	bid = id
	bstate = 0

	If centered Then bx = (GraphicsWidth()*.5) - (bwidth*.5) ;center on screen vertically

	Return b
End Function

Function updatebuttons()
	For b.button = Each button
		If RectsOverlap(mx,my,1,1,  bx, by, bwidth, bheight)
			If MouseDown(1) Then
				bstate = 1 ; button is being held down over button
				buttonheld = 1 
			Else
				bstate = 2 ; mouse is hovering over button with no button down
				If buttonheld = 1	; was the button down last time? If so, mouse has just clicked up.
					ID_clicked = bid ;this button has been clicked. set to ID of clicked button
					buttonheld = 0	;reset the button down value
				EndIf 					
			EndIf
		Else		; mouse is not over button
			bstate = 0	;normal state of button				
		EndIf
		
		DrawImage	bimage,bx,by,bstate ; draw the button to screen
	Next 
End Function

Function ButtonAction()
	;Use this function to take action based on which button has been pressed. Each time you make a button, give it a unique ID.
	;Then add a new case for that ID here.
	Select ID_clicked
		Case 1
			;this button ID has been clicked. Do stuff here
			info$ = "Button A has been clicked"
						
		Case 2
			;this button ID has been clicked. Do stuff here
			info$ = "Button B has been clicked"

		Case 3
			;this button ID has been clicked. Do stuff here
			info$ = "Centered button has been clicked"

		Case 5
			;this button ID has been clicked. Do stuff here
			info$ = "Image button has been pressed"

	End Select

	ID_clicked = -1

End Function


Comments :


Nate the Great(Posted 1+ years ago)

 hmmm... could be useful... thanks pongo!


pmc(Posted 1+ years ago)

 Exactly what I was looking for a couple of weeks ago. Thank you. I'll try it out.-pmc


_PJ_(Posted 1+ years ago)

 It's possible that the field ID is unnecessary - assuming that there isn't a requirement for duplicate id's.My reasoning is that as Type objects, the Handle() of each button instance can be used as the IDFurther savings on memory can be achieved by:Instead of maintaining a unique image for each especially if button images are either in multuple usage, or only ever Loaded once, Loading the correct images on creation of the first instance which uses it, but maintaining the image HANDLEs GLOBALLY could make this easier.incidentally, the Field for Image should not be declared as a string.The Position values can be stored as a single INT made of two SHORTS rather than two serparate INTSLikewiser for the Width/Height dimensions.


Yasha(Posted 1+ years ago)

 I don't think using the Handle as the ID really fits with what is going on here, because Handles are assigned at runtime and this is kinda reliant on the ID being known at compile-time so you can set up the Select structure accordingly. You can't rely on Handle returning a predetermined number, only that it will return some number; and therefore can't really rely on finding the right Case from it.