1. #1

    Adding Message To Frame

    Hola, so I am about to finish an add-on and release it, but I'm having a bit of trouble adding messages to the frame properly. At the moment it starts adding messages to the frame starting at the bottom, rather than the top.

    http://imgur.com/ct3wWsv

    Picture detailing what's happening. If I :SetInsertMode("TOP") it will start at the top, but it will also continue to put new messages above the previous messages which I do not want. I want to input my first message at the very top of the frame, and then continuously put more messages under that initial message as if it was a Word document. I can't use FontString because this addon will eventually go over the 4000 character limit.

    Any help is appreciated!

  2. #2
    Why don't you use one FontString per line, dynamically generating more as needed? It's what ScrollingMessageFrame does internally, too.

    ---------- Post added 2013-03-15 at 08:34 AM ----------

    Looking at your picture, here's my first impression of how I'd do it:

    - One FontString for the heading ("Vahalue - Tichondrius vs 2v2 Arena Teams")
    - A numerically-indexed table of tables for the entries. Each sub-table holds two FontStrings. These are positioned appropriately within a container, starting at the top. You might want to consider using a ScrollFrame for the container. If you do, make sure the label is outside the container, as you don't want to scroll it.

    Example:
    Code:
    -- Assuming that 'container' is the container frame mentioned above
    -- I'm not sure about the offset and height values. This is a drycoded example. Play around until it fits.
    
    container.entries = setmetatable({},{__index=function(t,v)
        local entryFrame = CreateFrame("Frame",nil,container)
        entryFrame:SetHeight(25)
        if v == 1 then
            entryFrame:SetPoint("TOPLEFT",container,"TOPLEFT",10,-10)
            entryFrame:SetPoint("TOPRIGHT",container,"TOPRIGHT",-10,-10)
        else
            entryFrame:SetPoint("TOPLEFT",t[v-1][3],"BOTTOMLEFT",0,-10)
            entryFrame:SetPoint("TOPRIGHT",t[v-1][3],"BOTTOMRIGHT",0,-10)
        end
    
        local text1 = entryFrame:CreateFontString(nil,"ARTWORK")
        text1:SetPoint("TOPLEFT")
        text1:SetPoint("TOPRIGHT")
        text1:SetFont("Fonts\\FRIZQT__.TTF",12,"OUTLINE")
        text1:SetTextColor(1,1,1)
        text1:SetJustifyH("LEFT")
        text1.frame = entryFrame
    
        local text2 = entryFrame:CreateFontString(nil,"ARTWORK")
        text2:SetPoint("BOTTOMLEFT")
        text2:SetPoint("BOTTOMRIGHT",
        text2:SetFont("Fonts\\FRIZQT__.TTF",12,"OUTLINE")
        text2:SetTextColor(1,1,1)
        text2:SetJustifyH("LEFT")
        text2.frame = entryFrame
    
        t[v] = {text1,text2,entryFrame}
        return t[v]
    end})
    
    -- assuming entryList is a numerically indexed table of tables. each sub-table contains two strings
    -- example: {{"1) Win - Loss: 6 - 1 (85%)","Gitta - Frostmourne,Archeia - Frostmourne"},{"2) Win - Loss: 25 - 5 (83%)","Bubblèwrap - Barthilas,Orion - Barthilas"}}
    -- these should have color codes, of course
    local function setExample(title,entryList)
        -- remember to set the label fontstring, too. this example doesn't do it.
        
        for i=1,#entryList do
            local e = entryList[i]
            local f = container.entries[e]
            f[3]:Show() -- f[3] is the entry's frame
            f[1]:SetText(e[1]) -- f[1] is the top fontstring
            f[2]:SetText(e[2]) -- f[2] is the bottom fontstring
        end
        for i=(#entryList+1),#container.entries do
            container.entries[i][3]:Hide() -- hide frames for all entries we aren't using
        end
    end
    All of the above is drycoded. All sizes, font sizes and offsets are thus pure guesswork. Errors may be contained.
    UI & AddOns expert | Interface & Macros moderator - My work

  3. #3
    Unfortunately I may be a little too deep to make such a fix. Here is a pastebin upload http://pastebin.com/RrCGAXm1, but it's 1800 lines and quite a mess since this is my first LUA project ever. 1580-1623 is an example of how I add messages to the frame. I'm actually also having an issue where if my minmaxvalue for the scrollbar is too high (or something) then the message is repeated as I scroll down (i think thats what happens anyways). Right now I simply want to loop through a table (which I do fine), AddMessage() to the ScrollFrame, and set the ScrollFrameBar's size properly so that the first line of text is the top, and the last line of text is the bottom of the scroll bar. If I could do something similar using FontString's I'm all for it since this is the absolute last thing I need to fix up before it is finished.
    Last edited by EulavValue; 2013-03-15 at 08:05 AM.

  4. #4
    Well, the problem here is you're not really using ScrollingMessageFrame for its intended purpose.

    If you'd like to adapt the code you pointed out to use my model, this is what you should change:
    1. Turn line 1583 from an AddMessage to a SetText on the label.
    2. Use ipairs instead of pairs on line 1584. pairs() is generic, while ipairs() is intended for numerically indexed sorted tables. The main difference is that ipairs() enforces sequence, while pairs() gives no such guarantee.
    3. Between lines 1588 and 1589, fetch the entry frame to use (from 'container.entries', in my example). pCount can be used as an index.
    4. Turn line 1618 from an AddMessage into a return.
    5. Turn line 1589 from an AddMessage into a SetText on the top FontString ([1] in my example).
    6. Turn line 1590 into a SetText on the bottom FontString ([2] in my example) using the return value we added in 4).
    7. Adapt and add the hide-unneeded-entries code from my example after line 1592. Use (pCount+1) as a starting value.



    PS: Something I wanted to point out while skimming over your code:
    Multiple string concatenation is inefficient in Lua. As there is no compiler optimization, multiple concatenation causes the operations to be executed one after another, creating and discarding each intermediate string in memory. (Extreme) example:
    Code:
    local str = "this".." ".."is".." ".."a".." ".."long".." ".."string"
    This creates the following strings in memory:
    Code:
    "this"
    "this "
    "this is"
    "this is "
    "this is a"
    "this is a "
    "this is a long"
    "this is a long "
    "this is a long string"
    It is more efficient to use native concatenation, such as string.format (which can be called as a method on any string, e.g. ("Found something: %s"):format("efficiency")) or table.concat (e.g. table.concat({"this","is","a","long","string"}," ")).


    PPS: You seem to have a dislike for scoping and using locals. Why is that? Any previous programming languages? I'm curious.
    Last edited by Treeston; 2013-03-15 at 09:07 AM.
    UI & AddOns expert | Interface & Macros moderator - My work

  5. #5
    I don't dislike scoping and using locals, but yeah I didn't use them very often in this add-on. Mostly because at first I didn't understand them and resulted to keeping everything global, and never went back to correct them. I started programming last year January and most of my knowledge has come from courses (comp sci degree). This add-on is my attempt to add to my knowledge of languages.

  6. #6
    Just make sure you give it a run over with Mikk's FindGlobals or equivalent and make sure you don't leak any of them. Regardless, for a first project, it's great, really. You don't want to see my first attempts at Lua. Trust me on that one.
    Last edited by Treeston; 2013-03-15 at 08:17 PM.
    UI & AddOns expert | Interface & Macros moderator - My work

  7. #7
    Thanks, and I'll be sure to use it after I finish this up. Forgot to mention but the programming language I learned initially was Java since my school focuses on it.

    Disregard, fixed.
    Last edited by EulavValue; 2013-03-16 at 03:41 AM.

  8. #8
    I'll just say that Java is not the optimal language for learning efficiency. It also explains your affection for object-style programming.

    PS: As a start, simply prefixing all the definitions in lines 12-50 (in your pastebin) with 'local' would help greatly. It won't make your code behave any differently assuming you only have one file.
    UI & AddOns expert | Interface & Macros moderator - My work

  9. #9
    totally offtopic, but i would like to know the name of your addon when your done. if what i think ur doing is correct, it would be interesting to see it when its live

  10. #10
    Yeah I haven't learned anything about efficiency other than than Big-O. Taking a Data Structures and Programming in C++ course starting Monday, so hopefully each will touch on efficiency and I'll be able to compare. May just have to learn it on my own time, though.

    I'll put up a link to the add-on wherever I end up putting it accoolnamehere. Hopefully before Monday since I'd like to be done before my new classes start.

  11. #11
    http://www.wowinterface.com/download...ssTracker.html

    Uploaded my add-on there if anyone who has viewed this thread is interested. I haven't been able to debug the 3v3 and 5v5 side of the database, and haven't done string.concat or anything like that, but once I know I've fixed up the majority of bugs (since I'm sure there will be some) I'll start working on efficiency slowly, or possibly just start a new project ;p.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •