Find a key-word in a string, and replacing it with a button [SOLVED-ISH]

Hi,

Ive been struggling with this for the last hour now.. and made abit of progress but have now hit a brick wall.

Right now i have a long string, i want to be able to find a word in that string and replace it with the same word, but a different colour, and have it so that i can press that word.

So far i can find the words in the string, replace them with _____ and then add in a new text object thats clickable, but i have no idea how i am supposed to know the X/Y co-ordinates of the word i subsituted so that my new text object can take its place.

Get what i mean lol?

heres what i have so far..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
--My array containing the words i want to replace..
for i=1, #glossWord do  
                local word = tostring(glossWord[i])
                
                --stockDesc is the string i want to substitute the new clickable words into..
                stockDesc = string.gsub(stockDesc, word, function (s)
                        local s2 = s
                        local nw = "_"
                        
                        --Get the length of the word im replacing so i know how many "_" to do..
                        local length = string.len(s)
                        for i=2, length do
                                nw = nw.."_"
                        end
                                
                        
                        --Function that creates the clickable word...
                        local function createWord(s)
                                local function changeScene(event)
                                        if event.phase == "ended" then
                                                print("changing Scene")
                                        end
                                        return true
                                end
                                
                                --New text position is set to 0,0 for now as i have no idea how i can make it the location of the replaced word..
                                local text = display.newText(s,0,0,"Helvetica",32)                              
                                text.xScale = 0.5; text.yScale = 0.5;
                                text:setReferencePoint(display.CenterLeftReferencePoint)
                                text:setTextColor(0,0,155,255)
                                text.name = s
                                text:addEventListener("touch", changeScene)
                                extraGroup:insert(text)
                        return true
                        end
                        createWord(s2)
                        
                        --return nw which is "_____"
                        return(nw)
                 end)
end

What about splitting the String, making a new one with the characters BEFORE the matched String occures and finding out it's length!
(I hope that made sence at all :> )

Will try to make you a little code example!

Hey fanta, thanks for the reply!

I think i know what you getting at.. i did try using..

1
local loc = string.find(stockDesc, word)

Oh, that's bad. For single line strings that should have worked out, but multiline is a problem!
I'm not sure if there's a way to detect it, since not only the lettersize variies, but the kerning/spacing inbetween the letters aswell.

Maybe using some of the textwrapper functions from the code database ( http://developer.anscamobile.com/code/multiline-text-width-pixel ) to make your own multiline textblocks, then stripping down each new textfield (one made for each row), search there for the word and then using the same technice.

Another problem is when using a new font, that it could actually overlap the text.

Maybe you can find a workaround :/

Yep i think thats going to have to be the way to do it..

At least that way i would know precisely how many characters there are per line, and therefore i can just multiply the X value by the amount of characters into the line the word is.

Its not exactly going to be precise placement of the replaced word, but its a start.

Thanks for the ideas fanta, if i get a working version im happy with i'll post it here if any others need it in the future.

Ok i think ive done it...

Its shody, and i havent test it with any other long strings, but for the current string im using it works :D haha.

Heres what it looks like atm..
Photobucket

Incase anybody wants to know now or in the future here is the code..

This block of code is what i made to find the words i want to replace, set those words to _____ and then create a new clickable word in its place...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
        -------------------------------------------------------------------------------------
-- *** check for words i want to replace, and create new text objects for them ***
--------------------------------------------------------------------------------------
--Setup new arrays for words i want to replace and where they are in the string etc...
local repString = {}; local repStringLength = {}; local repStringPos = {};
--Loop through the database of glossary words.
for i=1, #glossWord do
        local word = tostring(glossWord[i])
        
        if word == "Nugget Clasp" or word == "Pave" then
                word = string.lower(word)
        end
 
        stockDesc = string.gsub(stockDesc, word, function (s)
                local nw = "_"
                local loc = string.find(stockDesc, s)
                local length = string.len(s)
                
                for i=2, length do
                        nw = nw.."_"
                end
                nw = " "..nw.." "
                
                repString[i] = s
                repStringPos[i] = loc
                repStringLength[i] = length
                
                return(nw)
        end)
end
 
--Create the long list of text, wrapped to 40 characters per line...
local textBox = wrappedText(stockDesc, 40, 17, "Helvetica", {255,255,255},"","" )
textBox.x = 10; textBox.y = _H*0.35
extraGroup:insert(textBox)
 
 
--Add in our new button words...
for i=1,#repString do
        local pos
        local word = repString[i]
        if repStringPos[i] ~= nil then
                pos = repStringPos[i] + repStringLength[i]
        end
        local line
        
        --Reset the pos var so that is starts at 0 each line.
        --Set the line var so i know where to set the Y position of the new text objects..
        if pos ~= nil then
                if pos <= 40 then
                        line = 0
                elseif pos > 40 and pos <= 80 then
                        line = 1
                        pos = pos - 40
                elseif pos > 81 and pos <= 120 then
                        line = 2
                        pos = pos - 80
                elseif pos > 121 and pos <= 160 then
                        line = 3
                        pos = pos - 120
                elseif pos > 161 and pos <= 200 then
                        line = 4
                        pos = pos - 160
                elseif pos > 201 and pos <= 240 then
                        line = 5
                        pos = pos - 200
                end
 
                pos = pos - repStringLength[i] 
        end
        
        if word ~= nil and word ~= "nil" then
                local text 
                local function changeScene(event)
                        if event.phase == "ended" then
                                chosenWord = text.id
                                save()
                                director:changeScene("glossary","moveFromTop")
                        end
                        return true
                end
                --Add the new words here, which are clickable and take me to the glossary..
                text = display.newText(word,8+(pos*7.4),(_H*0.35)+22*line,"Helvetica",34) 
                text.xScale = 0.5; text.yScale = 0.5; text:setReferencePoint(display.CenterLeftReferencePoint);
                text:setTextColor(20,200,20,255); text.id = i;
                text:addEventListener("touch", changeScene)
                extraGroup:insert(text)
        end
end

Good job that you got it working :) Glad I could help in some way.

I guess you could also just make it the unsexy way and use WebPopups, HTML and Javascript to color small parts of the text (putting those into a span).

There are many ways :) And maybe the one using WebPopups could be more usefull, since you could style everything without the worries of destroying the textflow!

Chris

Thats very true..

The only problem with that method is that my HTML and javascript skills are extremely limited ;)

I can hopefully clean up my code and tweak it abit to leave less gaps inbetween the replacement words.
But for now it works, so im happy lol.

Haha :D

Yeah but googling for string functions in javascript and manipulating the dom isn't that hard :D

But well - if it works, then you're fine. Never change a running system ;)

Maybe I should write a little function that will do that stuff for you :)

Ok, it seems that the code i posted above only properly worked with that long string.. lol

Im in the process of rewriting it though to try and work with anything.. But thats not going all that well :P

If you would like to write a function, then that would be great thanks :)

Spend some time playing around, but since webPopups aren't supported in the Simulator and building the app takes too much time I can't really provide a code :/

(also i've had to search for a premade script, since I didn't know if jquery would be good to use or not).

The idea is:
Load the html file - either download from page or have it somewhere locally
Search the dom for the keywords and wrap a around it which can be styled.

The only problem: You can't really interact with this site using corona.
What you could do is making also an tag to link to other files that will work as a button.

It's a bit too much to do now for me, but maybe somehow will have the spare time :/

I wish you best luck!

Thanks for the tips, i may try that tomorrow!

I did manage to make a new function all together after my last attempt, as far as i can see, this one actually works (aslong as i stick to monospace fonts).

Now i just need to find a nice monospace font that actually works.. most the free monospace ones ive found so far just dont work :/

views:2139 update:2011/11/19 17:31:56
corona forums © 2003-2011