Thread Tools Display Modes
05-07-14, 05:18 PM   #1
Billtopia
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 110
EditBox with line numbers

I was wondering if anyone knows of a way to have line numbers attached to an editbox like in any standard IDE for coding you can have line numbers. I have written an addon called SlashMagic that allows the user to input little scriptlettes and have them turned into slash commands. It has even been updated to allow aliases for the commands now. I am trying to figure out a way to make the built in editor for the lua more IDE like. I looked at _devpad and got a few ideas then all mixed up trying to implement what they did.
I have tried using a scroll frame attached to a seperate frame with a fontstring and editbox attached to the seperate frame and it almost works except as you type the editbox leaves the 'window' of the scroll frame. I even figured out how to measure the strings within the editbox to see if they are wrapped lines or are terminated by <CR>s

Only real problem with this approach seems to be that even though the multiline editbox does grow vertically the backdrop remains the same size, and the editbox can and will leave the screen.


I currently have restored the code on my addon back to a non-scrolling editbox but if someone puts in a long snippet of code the editbox will still go off the screen.
  Reply With Quote
05-07-14, 07:03 PM   #2
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Look at WoWLua: http://www.wowinterface.com/download...66-WowLua.html
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
05-07-14, 07:42 PM   #3
Billtopia
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 110
I am not sure what is going on there... multiple overlapping editboxes overlaying a scrolling message frame? I get lost in the XML lol
  Reply With Quote
05-08-14, 09:59 AM   #4
ravagernl
Proceritate Corporis
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 1,176
  1. Make a fontstring
  2. when the editbox updates(onKeyUp), count the number of lines
  3. Update the font string with a for loop(1..numlines)
  Reply With Quote
05-09-14, 08:17 PM   #5
Billtopia
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Apr 2009
Posts: 110
so this is what I came up with with an explanation and it even works



lua Code:
  1. local eframe = 0
  2. local oldpos = -1
  3. local oldLinePixels= -1
  4. me2:SetScript("OnUpdate", function(self, elapsed)
  5.     eframe = eframe + 1
  6.     if eframe < 2 then return end
  7.     eframe = 0
  8.    
  9.     local cursorPos = me.CodeFrameEBox:GetCursorPosition()
  10.     if oldpos ~= cursorPos then
  11.         local pos = cursorPos
  12.         local linewidth = me.CodeFrameEBox:GetWidth()
  13.         local CRs
  14.         local code = { string.split("\n\r",me.CodeFrameEBox:GetText()) }
  15.         local ccode = { string.split("\n\r",coloredGetText(me.CodeFrameEBox)) }
  16.         local linestring = ""
  17.         local line = false
  18.         local currentLinePixels = 0
  19.        
  20.         -- Line Numbers section
  21.         for x = 1, #code do
  22.             StrLen:SetText( code[x]:len() >0 and code[x] or "X")
  23.            
  24.             CRs = math.floor(StrLen:GetStringHeight() / 12)
  25.             linestring = linestring..x..":"..string.rep("\r", CRs)
  26.            
  27.             if not(line) and pos - ccode[x]:len() <= 0 then
  28.                 line = x
  29.             elseif not( line ) then
  30.                 currentLinePixels = currentLinePixels + (CRs * 12)
  31.                 pos = -1 + pos - (ccode[x] and ccode[x]:len() or 0)
  32.             end
  33.         end
  34.         linestring = string.gsub( linestring, ("%d:"):format(line), ("|cFF00FF00%d:|r"):format(line), 1)
  35.         me.LineNumbers:SetText(linestring.."\n\n\nEOF\r")
  36.         oldpos = cursorPos
  37.        
  38.         -- line / col section
  39.         if pos == 0 then
  40.             me.pos:SetText( ("line: %d  char: %d"):format(line, 0))
  41.         else
  42.             local tempString = ccode[line] and ccode[line]:sub(1,pos) or ""
  43.             tempString = tempString:gsub("|c%x%x%x%x%x%x%x%x", "")
  44.             tempString = tempString:gsub("|r", "")
  45.             me.pos:SetText( ("line: %d  char: %d"):format(line, tempString:len()))
  46.         end
  47.        
  48.         -- scroll frame adjust section
  49.         if oldLinePixels ~= currentLinePixels and not( IsMouseButtonDown("LeftButton") ) then
  50.             local displayPixels = me.EBoxOverlay:GetHeight() --
  51.             local displayTop = me.ScrollFrame:GetVerticalScroll()
  52.             local displayBottom = displayTop + displayPixels
  53.             local edge = 48
  54.        
  55.             if currentLinePixels > displayTop + edge and currentLinePixels < displayBottom - edge then
  56.                 -- within viewing window so do nothing
  57.             elseif currentLinePixels < displayTop + edge and displayTop > 1 and currentLinePixels < oldLinePixels then
  58.                 me.ScrollFrame:SetVerticalScroll( currentLinePixels - edge )
  59.             elseif currentLinePixels > displayBottom - edge then
  60.                 me.ScrollFrame:SetVerticalScroll( currentLinePixels - displayPixels + edge)
  61.             end
  62.             oldLinePixels = currentLinePixels
  63.         end
  64.     end
  65.    
  66. end)

the editbox has a fonstring running down the left side of it and they are both attached to the scroll frame.
no messing with history lines for the editbox or any scrollingmessageframe there is a frame overlaying the editbox's visible area with the backdrop set to it so that the backdrop doesn't go scrolling around the screen.

it is in an OnUpdate as the the editing windows just about fills the screen (80% each direction) and it shows no real drop in fps when editing the code. when the cursor position changes in the me.CodeFrameEBox it then pulls both the text formatted by FAIAP and the un-keyword colored text and splits it by lf/cr into a table.


it then does a loop sending the uncolored text to a fontstring set the same width as the editbox, grabs its height and divides by the font height. (I tried just doing it by length of the string but that could not properly predict wordwrap)


it then increments the line number string adding blank lines if the code wraps across lines


it then checks if the cursor position is in the current line by comparing to the colored text
if not it increments the pixel count by the height of the code if it is it sets the line


finished with the loop it changes the current line number on the side to green to distinguish it from the other lines
it sets the line number string


it then takes the position within the colored text sting left from the loop and if it is 0 it knows you are at the start of the string, if not it has to split the string at pos, strip the FAIAP code coloring then get the length of the left over string to figure the position of the cursor in the edit box


then to adjust the scrolling frame by the active line being editied I use the height of the overlay which is set where the "window" of the editbox on the scroll frame is. (there is no predetermined size... all points are relative by screen size)


and yes the mouse check is important as if you don't check for the mouse being down you end up doing all sorts of text selection in the editbox.


figuring out the math for the scroll frame was a bit of a pain but it all works now

Last edited by Billtopia : 05-09-14 at 08:23 PM. Reason: a little more info
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » EditBox with line numbers

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off