Dynamic Glossy Buttons

BlitzMax Forums/BlitzMax Programming/Dynamic Glossy Buttons

siread(Posted 2010) [#1]
I've been working on my own gui system lately (sure there are loads out there and Fry's is excellent but I want to have keyboard/joypad control) and I came up with a method for creating nice buttons without needing to load in any images. Check it out...



The buttons have no function in this code, it's just an example of how to draw them. I'm sure there is a nicer method for setting the alphagrid over the corners of the pixmap, so any help with that would be much appreciated.

Oh, and make sure you load in a nice font. :)

SuperStrict
Graphics(600,400)
SetBlend(ALPHABLEND)
SetClsColor(192,192,192)
' Local fnt:TImageFont = LoadImageFont("trebucbd.ttf", 16, SMOOTHFONT)
' SetImageFont(fnt)

Local btn1:TButton = TButton.CreateButton("btn_1", "X", 550, 10, 40, 40, "FF0000")
Local btn2:TButton = TButton.CreateButton("btn_2", "Dynamic Glossy Buttons", 100, 10, 400, 60, "FFFFFF")
Local btn3:TButton = TButton.CreateButton("btn_3", "Nice Colour", 200, 100, 200, 100, "00FF00")
Local btn4:TButton = TButton.CreateButton("btn_4", "Smooth Corners", 100, 220, 400, 50, "FFFF00")
Local btn5:TButton = TButton.CreateButton("btn_5", "No pngs needed!", 150, 290, 300, 20, "AA00FF")
Local btn6:TButton = TButton.CreateButton("btn_6", "Enjoy!", 250, 320, 100, 30, "0000FF")

Repeat
	Cls
	TButton.DrawAll()
	Flip
Until KeyHit(KEY_ESCAPE) Or AppTerminate()


Type TButton
	Global list:TList
	Global alphagrid:Int[][] = [[0,0,0,0,128,192],[0,0,64,192,255,255],[0,64,255,255,255,255],[0,192,255,255,255,255],[128,255,255,255,255,255],[192,255,255,255,255,255]]		
	
	Field name:String
	Field txt:String
	Field x:Int
	Field y:Int
	Field w:Int
	Field h:Int
	Field hexcol:String
	Field image:TImage
	
	Method New()
		If Not list Then list = CreateList()
		list.AddLast(Self)
	End Method
	
	Function CreateButton:TButton(name:String, txt:String, bx:Int, by:Int, bw:Int, bh:Int, hexcol:String)
		Local b:TButton = New TButton
		b.name = name
		b.txt = txt
		b.x = bx
		b.y = by
		b.w = bw
		b.h = bh
		b.hexcol = hexcol
		b.CreateButtonImage()
		Return b
	End Function
	
	Method CreateButtonImage()
		If w < 12 Or h < 12 Then Return
			
		Local pix:TPixmap = CreatePixmap(w, h, PF_RGBA8888) 
		pix.ClearPixels(0)
		
		' First fill the pixmap with greyscale colour
		For Local x:Int = 0 To w-1
			For Local y:Int = h-1 To 0 Step -1
				Local col:Float = 255.0-(96.0/h)*y				' Base the gradient on the y co-ordinate
				If y >= h/2 Then col = 245.0-(96.0/h)*y			' Change it slightly half-way up
				pix.WritePixel(x,y,GetRGBA(col,col,col,255))
			Next
		Next
	
		' Now use the alphagrid to create the top left corner
		For Local x:Int = 0 To 5
			For Local y:Int = 0 To 5
				' Get existing pixel colour
				Local p:Int = pix.ReadPixel(x,y)
				Local r:Int = (p Shr 16) & $FF
				Local g:Int = (p Shr 8) & $FF
				Local b:Int = (p Shr 0) & $FF
				
				' Replace with alpha
				Local a:Int = alphagrid[x][y]
				pix.WritePixel(x,y,GetRGBA(r,g,b,a))
			Next
		Next
		
		' Top right corner
		Local bx:Int = w-1
		For Local x:Int = 0 To 5
			For Local y:Int = 0 To 5
				Local p:Int = pix.ReadPixel(bx,y)
				Local r:Int = (p Shr 16) & $FF
				Local g:Int = (p Shr 8) & $FF
				Local b:Int = (p Shr 0) & $FF
				Local a:Int = alphagrid[x][y]
				pix.WritePixel(bx,y,GetRGBA(r,g,b,a))
			Next
			
			bx:-1
		Next
				
		' Bottom left corner
		For Local x:Int = 0 To 5
			Local by:Int = h-1
			For Local y:Int = 0 To 5
				Local p:Int = pix.ReadPixel(x,by)
				Local r:Int = (p Shr 16) & $FF
				Local g:Int = (p Shr 8) & $FF
				Local b:Int = (p Shr 0) & $FF
				Local a:Int = alphagrid[x][y]
				pix.WritePixel(x,by,GetRGBA(r,g,b,a))
				by:-1
			Next
		Next
		
		' Bottom right corner
		bx = w-1
		For Local x:Int = 0 To 5
			Local by:Int = h-1
			For Local y:Int = 0 To 5

				Local p:Int = pix.ReadPixel(bx,by)
				Local r:Int = (p Shr 16) & $FF
				Local g:Int = (p Shr 8) & $FF
				Local b:Int = (p Shr 0) & $FF
				Local a:Int = alphagrid[x][y]
				pix.WritePixel(bx,by,GetRGBA(r,g,b,a))
				by:-1
			Next
			
			bx:-1
		Next
		
		image = LoadImage(pix)
	End Method
	
	Function DrawAll()
		For Local b:TButton = EachIn list
			b.Draw()
		Next
	End Function
	
	Method Draw()
		If image
			' Button shadow
			SetColor(0,0,0)
			SetAlpha(0.5)
			DrawImage(image, x+1, y+1)
			
			' Button
			SetHexColour(hexcol)
			SetAlpha(1)
			DrawImage(image, x, y)
			
			' Text position
			Local tx:Int = x+(w/2)
			tx:-TextWidth(txt)/2
			
			Local ty:Int = y+(h/2)
			ty:-TextHeight(txt)/2

			' Shadow
			SetColor(0,0,0)
			SetAlpha(0.25)
			DrawText(txt, tx+1, ty)

			' Text
			SetAlpha(1)
			DrawText(txt, tx, ty-1)
		End If
	End Method
End Type

Function GetRGBA:Int(r:Int, g:Int, b:Int, a:Int = 0)
     Return a Shl 24 | r Shl 16 | g Shl 8 | b Shl 0
End Function

Function SetHexColour(col:String)
	Local r:Int, g:Int, b:Int
	r = Int("$"+col[0..2])
	g = Int("$"+col[2..4])
	b = Int("$"+col[4..6])
	SetColor(r, g, b)
End Function


Last edited 2010

Last edited 2010


wmaass(Posted 2010) [#2]
Always looking for new GUI goodness! I have been using FryGui for a lot of stuff lately. I was turned onto it by what you were able to do with it. Thanks for sharing this stuff.