Small Scroll Bar Example

BlitzMax Forums/BlitzMax Programming/Small Scroll Bar Example

Hi guys, first off: I've tried the new search feature but it's not really helping much. Second, I've had a look in the toolbox but all the GUI examples are too complicated to understand. They're all built together and have dependencies and such.

What I'm looking for is a small example of a scroll bar. It's the maths I'm getting stuck on. I want to be able to click on the middle slider button, hold down and affect the value. I can draw it fine, it's just the maths of what that vertical y position translates to in value terms.

Has anyone got a very simple example of this as some standalone code? Or maybe some tips on the actual maths of it all.

Any help appreciated,
Matt

Are you using MaxGUI? If so have you seen this ?
If this is your own code then the trick is to have the slider act from 1-100 (e.g. a percentage) and do the same with whatever it is you're scrolling.
e.g. imagewidth= 256 then each pixel is 2.56% which you map onto your scrollbar (unless I have misunderstood).

I have MaxGUI but want to program my own for a full screen game. Ahhh!!!! I'm trying to visualise the code but I can't. It's really frustrating when this happens.
local data_height = 500 
local scrollbar_height = 120
local value# = 25.0 ' %
local scroll_value#=(data_height/100.0) * value
' = (500.0/100.0) * 25 = 125
' So...
local scrollButtonY = ... not sure

So, when I'm at 25% scroll the data will be scrolled by 125 pixels. Riiiiight. I'm with it. So how do I translate this into a scroll button like the ones you hold down and move up and down?

Anyone got any code they'd care to share, please?

Cheers!
Matt

Not complety sure what your asking for but heres somting:
Type TVScroll
	Field x , y , w , h
	
	Field swp# 		' How much percentage dose the scroll bar take up
	Field svp# 		' Scroll bars percantage value
	Field spi# = 1 	' Percentage increase
	
	Field totr#		' Total range
	
	Method Render()
		SetColor 100, 100, 100
		DrawRect x , y , w , h
		SetColor 255 , 255 , 255
		DrawRect x + ((svp / 100.0) * w), y , (swp / 100.0) * w, h
	End Method
	
	Method MoveUp()
		svp:+ spi
		If svp > 100 Then svp = 100 ' Simple range checks
	End Method
	
	Method MoveDown()
		svp:- spi
		If svp < 0 Then svp = 0
	End Method
	
	Method GetRangeValue#()
		Return (svp / 100.0) * totr ' Get the percentage value of a max range
	End Method
	
	Method SetRange(_range#)
		totr = _range
	End Method
	
End Type

Graphics 800 , 600

Global sv:TVScroll = New TVScroll
sv.x = 10
sv.y = 10
sv.w = 400
sv.h = 22
sv.swp = 10
sv.totr = 1000 ' Offset this if you want

While Not KeyDown(KEY_ESCAPE)
	
	Cls
	
	sv.render()
	
	DrawText sv.GetRangeValue(), 10, 100
	
	If KeyDown(KEY_UP) Then sv.MoveUp()
	If KeyDown(KEY_DOWN) Then sv.MoveDown()
	
	Flip
	
Wend


Use the up/down arrow keys to 'scroll'. of course it dosent draw the scroll bar correctly but its late and i'll let you try and fix that, or some one else as the case may be.

Play around with it and let us know what you come up with.

also you could check out my gui lib (highgui, link in sig below) for how i did the scroll bars in that.

Ahhhhhhhhhhhhhhhhhhhhh!!! Help me! I'm slowly going mad. I'm trying to sort out line 35-ish. How do you translate the mouseY() into the value? Ahhh!! Banana crayon! I'm going insane!

Strict

Type TVScroll
	Field x , y , w , h
	
	Field swp# 		' How much percentage dose the scroll bar take up
	Field svp# 		' Scroll bars percantage value
	Field spi# = 1 	' Percentage increase
	
	Field totr#		' Total range
	Field mouseHitY#
	Field mouseHitSPV#
	
	Field view_x,view_y,view_w,view_h,viewPortEnabled=0
	
	Method Render()
				
		Local height=((swp/100.0)*(h))		
		SetColor 100, 100, 100
		DrawRect x , y , w , h+height
		SetColor 255 , 255 , 255				
		Local v=(((svp/100.0) * h))		
		DrawRect x,y+v,w,height
		
		If MouseDown(1)
			If mousehit1 And mouseHitY=0 And mousein(x,y+v,w,height)
				mouseHitY=MouseY()
				mouseHitSPV=svp
			EndIf
		Else
			mouseHitY=0
			mouseHitSPV=0
		EndIf
		If mouseHitY And MouseDown(1)
			mouseHitSPV = MouseY()-mouseHitY
			svp=mouseHitSPV 
			If svp < 0 Then svp=0
			If svp > 100 Then svp=100
		EndIf		
	End Method
	
	Method MoveUp()
		svp:+ spi
		If svp > 100 Then svp = 100 ' Simple range checks
	End Method
	
	Method MoveDown()
		svp:- spi
		If svp < 0 Then svp = 0
	End Method
	
	Method GetRangeValue#()
		Return (svp / 100.0) * totr ' Get the percentage value of a max range
	End Method
	
	Method SetRange(_range#)
		totr = _range
	End Method
	
	Method enableViewPort()
		SetViewport view_x,view_y,view_w,view_h
	End Method

	Method disableViewPort()
		SetViewport 0,0,GraphicsWidth(),GraphicsHeight()
	End Method	
			
	Method setScrollBarViewPort(x1,y1,w1,h1)
		view_x=x1
		view_y=y1
		view_w=w1
		view_h=h1
	End Method
	
	Method setCoords(x1,y1,w1,h1, swp1,totr1)
		x=x1;y=y1;w=w1;h=h1;totr=totr1
		swp=swp1
		If swp1=-1
			swp=(100.0/totr)
		EndIf
	End Method
	
	Method mouseIn(x1,y1,w1,h1)
		Local mx=MouseX()
		Local my=MouseY()	
		If mx>x1 And mx<x1+w1
			If my>y1 And my<y1+h1
				Return True
			EndIf
		EndIf	
		Return False
	End Method	
End Type



Graphics 800 , 600

Global mousehit1=0

Global sv:TVScroll = New TVScroll
	sv.setCoords(520,10,14,250,15,500)
	sv.setScrollBarViewPort(10,10,520,250)



While Not KeyDown(KEY_ESCAPE)	
	Cls
	mousehit1=MouseHit(1)
		
	sv.render()
	
	sv.enableViewPort()
	DrawText "Value: "+sv.GetRangeValue(), 10, 10-sv.GetRangeValue()
	DrawText "MouseHitY: "+sv.mouseHitY,10,20-sv.GetRangeValue()
	DrawText "MouseHitSPV: "+sv.mouseHitSPV,10,40-sv.GetRangeValue()
	DrawText "Calc: "+sv.svp,10,60-sv.GetRangeValue()
	For Local i=1 To 20
		DrawText "Information here",10,(60+(20*i))-sv.GetRangeValue()
	Next
	sv.disableViewPort()
	
	DrawText "HELLO",400,400
	
	If KeyDown(KEY_DOWN) Then sv.MoveUp()
	If KeyDown(KEY_UP) Then sv.MoveDown()
	
	Flip
	
Wend


Strict
Graphics 640,480,0

Local ScrollBar:TScrollBar = New TScrollBar
ScrollBar.SetShape(5,5,20,300)	' <- Position the scrollbar
ScrollBar.SetRange(100,10)		' <- there is 100 items and we can see 10 of them

Repeat
	Cls
	ScrollBar.Render()
	DrawText(ScrollBar.Pos,30,5)
	Flip	
Until KeyDown(KEY_ESCAPE)
End

' ------------------------------------------------------------------------------------

Type TScrollBar

	Field X:Int, Y:Int, W:Int, H:Int
	Field Total:Int	= 10
	Field Visible:Int = 1
	Field Pos:Int	
	Field Drag:Int = False
	Field Difference:Int
	
	Method Render()
		
		Local pv# = Float(h-4)/total
		Local by# = Y+2+(pv*pos)
		Local bh# = pv*Visible	; If bh<1 Then bh=1

		If MouseDown(1)
			If Drag=False
				If MouseX()>X And MouseX()<X+W
					If MouseY()>Y And MouseY()<Y+H
						If MouseY()<by
							Pos:-1 
						ElseIf MouseY()>by+bh
							Pos:+1 
						Else
							Drag = True
							difference = by - MouseY()
						EndIf
					EndIf
				EndIf
			EndIf
		Else
			Drag=False
		EndIf

		SetColor(255,255,255) ; DrawRect(X,Y,W,H)
		SetColor(0,0,0) ; DrawRect(X+1,Y+1,W-2,H-2)	

		If Drag
			Pos = ((MouseY()-Y)+Difference)/pv 
			SetColor(255,200,0)
		Else
			SetColor(255,255,255)
		EndIf
		
		If Pos+Visible>Total Then Pos=Total-Visible
		If Pos<0 Then Pos=0
		by# = Y+2+(pv*pos)
		
		' clip incase total<visible
		If by#<y+2 Then by=y+2
		If bh#>h-4 Then bh=h-4
		
		DrawRect(x+2,by,W-4,bh)
		
	EndMethod
	
	' ------------
	
	Method SetShape(X:Int, Y:Int, W:Int, H:Int)
		Self.X=X ; Self.Y=Y ; Self.W=W ; Self.H=H
	EndMethod
	
	Method SetRange(total:Int,visible:Int)
		Self.Total   = total
		Self.Visible = visible
	EndMethod
	
EndType


he, now i see what he was asking for. :(

Thats a nice scrolly papa.

Dudes, you both rock. Thank you so much for your help. I see the maths now. Very nice work both of you.

Matt

I think papa rocks more.

Btw If you want some 'framework' to base your in-game gui code then check out my
GUI Base Code/GUI Base Code :p

Here Is a Example & full source of how to use it.

Wow. Sweet resource Diablo. I'll certainly check that out. Thanks for sharing.

Matt