Clicking on a single word in a sentence?

BlitzMax Forums/BlitzMax Programming/Clicking on a single word in a sentence?

Chroma(Posted 2013) [#1]
Let's say I have a few sentences stored in a string array:
Local str_array:String[] = ["The man is a nice guy.","Hey what are YOU doing?","Today is a beautiful day!"]

For i:Int = 0 to str_array.Length-1
     DrawText str_array[i], 10, 10 + i * 20
Next 

Ok now, I want to make it so the word YOU is in bold and clickable with the mouse. How would you tackle this problem?


col(Posted 2013) [#2]
Never mind, wrong post entirely!! :D

But to answer your question I suggest making a 'ClickableText' type that will hold the text and the coords of said text. You need to store the dimensions (width and height) then use a simple 'mouse in box' test along with the mouse button status to know if theyve clicked within the texts box area.


Chroma(Posted 2013) [#3]
Ah, nice col. So it's not kept with the actual string but totally separate. Easier to do BOLD on it too that way.

But I came up with this pseudo-code before I saw your post so I might as well post it I guess.


Local line:String = " When are YOU going to college?"
Local keyword:String = "YOU"

'get keyword width and height
Local kw_width:Int = TextWidth(keyword)
Local kw_height:Int =  TextHeight(keyword)

'find index position of first letter of keyword
Local kw_index:Int = Instr(line,keyword)

'find x pixel offset from start of line to start of keyword
Local offset_x:Int =TextWidth( Left$(line,0,kw_index-1) )

'check for mouse over
If MouseOver(pos.x + offset_x, pos.y, kw_width, 18)
	'Do Something
EndIf

Function MouseOver:Bool(x:Int, y:Int, w:Int, h:Int)
	If MouseX() < x Then Return False
	If MouseX() > x + w Then Return False
	If MouseY() < y Then Return False
	If MouseY() > y + h Then Return False
	Return True
End Function



Chroma(Posted 2013) [#4]
So have a paragraph Type and then a ClickableText Type that works together. And in the paragraph line:String[] just pad where the clickable text goes with spaces.

I like it!


Chroma(Posted 2013) [#5]
Or you could have a string array of sentences, and process them into a bunch of single words that are draw at the correct positions but making them all clickable. I will have to play with this a bit.


col(Posted 2013) [#6]
You got the idea ;)

Separate the logic of handling the words and how they will be rendered from the actual rendering part itself then you can control and render the text any way you wish.


Chroma(Posted 2013) [#7]
Here's the TextLink Type. It's a bit like HTML hence the change to TextLink. This is for a Text Adventure where the words the player clicks on can be anywhere on the page. Hoping to migrate this to monkey soon. I still like prototyping in BMax.

So basically there will be a Page Type with a List of TextLinks that will take you to different parts of the eBook. Similar to a CYOA book.
Local sentence:String[] = ["A cold wind howls through","the nearby trees.  You look up and","and see small path leading North."]

Local go_north:TextLink = New TextLink(sentence[3], "North", 3)

'Pseudo-Main-Loop
If go_north.Clicked() Then TurnTo(go_north.page)

Class TextLink
	Field id:Int
	Field text:String
	Field page:Int

	Field pos:Vec2
	Field width:Int
	Field height:Int

	Field alpha:Float
	Field color:Int[]
	Field rotation:Float
	Field scale:Vec2

	Field clicked:Int

	Method New(line:String, kw:String, line_row:Int, line_spc:Int = 5)
		Self.kw = kw
		Self.width = TextWidth(kw)
		Self.height = TextHeight(kw)
		Local kw_index:Int = Instr(line, kw)
		Self.pos = New Vec2(TextWidth(Left$(line,0,kw_index-1), line_row * Self.height + line_spc)
	End Method

	Method Update()
		If Self.MouseOver
			If MouseDown()  and Self.clicked = 0 Then Self.clicked = 1
			If Self.clicked = 1 and Not MouseDown() Then Self.clicked = 2
		Endif
	End Method

	Method Draw(offset:Vec2)
		DrawText Self.kw, Self.pos.x + offset.x, Self.pos.y + offset.y
	End Method

	Method MouseOver:Bool()
		If mouse_x < Self.offset.x + Self.pos.x Then Return False
		If mouse_x > Self.offset.x + Self.pos.x + Self.width Then Return False
		If mouse_y < Self.offset.y + Self.pos.y Then Return False
		If mouse_y > Self.offset.y + Self.pos.y + Self.height Then Return False
		Return True 
	End Method

	Method Clicked:Int()
		Return (Self.clicked > 1) 
	End Method
End Class



Chroma(Posted 2013) [#8]
Would also be cool to have a hover option with a little popup hint box so people could hover over Bold words to give a little more character background. Just a thought!


col(Posted 2013) [#9]
Looks good already. You now have complete control and can do anything your imagination lets you. You could also have a seperate 'TextAnimation' type that could be called that could handle any animation and effects. New effects are then easy to plugin.

Good work.