Thread Tools Display Modes
02-10-13, 05:34 AM   #1
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Help on ScrollFrame with LUA

Hi all,

I'd like to add a simple scrollframe to my addons to show a list of items (names).
The two book I have explain the scrollframe with the use of xml to build the frames.
And the web links I found usually follow this method.

I prefer if possible to avoid this approach and so I am trying to find some links, addons, code to check how this can be implemented with the plain LUA api interface.

I have tried to convert the xml approach to lua code but I didn't succeded.


Thanks very much for any inputs.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
02-10-13, 03:20 PM   #2
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Scroll frames are pretty annoying before you know their workings (well even after you know, too), but here is the simplest implementation I can come up with of a mostly working example. (you probably need to create a font string for the buttons and, of course, fill the list with something)
Code:
local NUM_BUTTONS = 8
local BUTTON_HEIGHT = 20

local list = {} -- put contents of the scroll frame here, for example item names
local buttons = {}

local function update(self)
	local numItems = #list
	FauxScrollFrame_Update(self, numItems, NUM_BUTTONS, BUTTON_HEIGHT)
	local offset = FauxScrollFrame_GetOffset(self)
	for line = 1, NUM_BUTTONS do
		local lineplusoffset = line + offset
		local button = buttons[line]
		if lineplusoffset > numItems then
			button:Hide()
		else
			button:SetText(list[lineplusoffset])
			button:Show()
		end
	end
end

local scrollFrame = CreateFrame("ScrollFrame", "MyFirstNotReallyScrollFrame", UIParent, "FauxScrollFrameTemplate")
scrollFrame:SetScript("OnVerticalScroll", function(self, offset)
	FauxScrollFrame_OnVerticalScroll(self, offset, BUTTON_HEIGHT, update)
end)

for i = 1, NUM_BUTTONS do
	local button = CreateFrame("Button", nil, scrollFrame:GetParent())
	if i == 1 then
		button:SetPoint("TOP", scrollFrame)
	else
		button:SetPoint("TOP", buttons[i - 1], "BOTTOM")
	end
	button:SetSize(96, BUTTON_HEIGHT)
	buttons[i] = button
end
This is a "faux" scroll frame, named so because it doesn't actually scroll. The scroll bar merely gives you an offset value, telling you which part of your list you should display in the "view area". It is intended to be used for simple lists, where the content is visually consistent. (such as the scroll frame where you select which battleground to queue for)

NUM_BUTTONS is the max amount of buttons/frames that will be visible at any one time in the view area, and BUTTON_HEIGHT is the height of these frames. These help deterrmine the position of the scroll bar and more.

The update function will be called everytime you actually scroll, and will reflect the new "view area". The corrent button height and the update function must always be passed to FauxScrollFrame_OnVerticalScroll in the "OnVerticalScroll" handler, as shown.

In the update function you will want to call FauxScrollFrame_Update(self, numItems, NUM_BUTTONS, BUTTON_HEIGHT) to set the scroll bar position. numItems is the total amount of items the scroll frame should represent. In your case, the number of items. You then need to get the offset, which represents the number of frames you have scrolled past. After this we can iterate over all the frame and set them up. The lineplusoffset variable here represents the effective index of your list of items. Assuming 8 buttons; when at the top of the list, offset will be 0, and so items 1 through 8 will be shown. If you scroll past 4 buttons, offset will be 4 and items 5 through 12 will be shown ((1 through 8) + 4). Frames will need to be hidden if the total amount of items is less than the number of items the frame can display at any one time. (< 8, in this case)

Make sure you don't create the subframes as children of the scroll frame itself; then they will be hidden if the size of your list does not exceed the number of items the frame can show.

Maybe this was more than you needed, but there you go. Feel free to ask for more info.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
02-10-13, 04:57 PM   #3
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Thanks so much for your reply.
I'll begin to study your code now ... :-)

Thanks again.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
02-11-13, 03:04 AM   #4
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
After a little bit of coding I am not able to display anything inside , probably because I think I miss something more :-/

I have in my addon a defined config frame in this way:

Lua Code:
  1. local options = CreateFrame("Frame", ADDON.."Options", InterfaceOptionsFramePanelContainer)
  2. [...]

and so I changed your code in this way:

Lua Code:
  1. local scrollFrame = CreateFrame("ScrollFrame", "MyFirstNotReallyScrollFrame", options, "FauxScrollFrameTemplate")

Then I begin to populate the list array:

Lua Code:
  1. local list = {"aaa", "bbb", "ccc" }

But I don't get any output (nor errors).

I think I miss the frame to be displayed if I understand well what you wrote to me.

Thanks for attention.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
02-11-13, 06:24 AM   #5
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
You need to call the update function manually once to "initialize" it. Might be it.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
02-11-13, 08:40 AM   #6
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
It doesn't work either.

I have double checked everything again and again but I am not able to see any outputs even if I add a :

Lua Code:
  1. update(scrollFrame)

to manually initialize the frame as you suggest.

If I have understood your post, the scrollframe should be the parent frame that will contain the inner scroll child... And so I need another frame to contain all the other things I wanna to be scrolled ...

But here I really don't understand where is this second frame, where I could add, in example, the buttons.

I am sorry if it is a silly question, but I am really lost now :-)

Thanks again for you replies.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
02-12-13, 01:52 AM   #7
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Interesting. I'm currently in the same boat. Setting up my first config panel atm.

http://www.wowinterface.com/forums/s...75&postcount=6

Currently into getting my classes up and running. Never created my own classes.

I need a scrollframe aswell. My ScrollFrame should fit right into the huge yellow space:
http://imgur.com/a/ecy2H

It should containt a bunc of Sliders/DropDownMenus/Buttons. I hope this is possible because I read ScrollFrame just hide frames while scrolling while showing others.

The thread will be a big help anyway. Thanks.
Maybe I need to create a sort of "lineFrame" first that I can show/hide.

gmarco if you need help on uipanel template stuff you check out:
http://code.google.com/p/rothui/sour.../wow5.0/rTest/
http://code.google.com/p/rothui/sour....0/rTestPanel/

Those are my test addons.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 02-12-13 at 01:58 AM.
  Reply With Quote
02-12-13, 06:49 AM   #8
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
Hi Zork,
thanks for your reply . I surely check your code and study it.
Let's see if finally I succeded in learning the use of all these frames even if I really don't understand why lombra code will not work for me.
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
02-12-13, 07:16 AM   #9
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
SetText is there yes, but the button needs a font string to display any text. (or maybe it has one by default, can't actually remember)

Either way, the scroll frame needs dimensions and a position before it'll show up.

@ Zork:
Since FauxScrollFrameTemplate is best suited for items with identical height, you might be better off using a real scroll frame. Or it could work if you created identical frames for each widget, as you said.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
02-12-13, 09:25 AM   #10
gmarco
An Onyxian Warder
 
gmarco's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 362
I am doing good progress

The code finally is displaying something :-)

Lua Code:
  1. local NUM_BUTTONS = 8
  2. local BUTTON_HEIGHT = 20
  3. local BUTTON_WIDTH = 96
  4.  
  5. local list = {"aaaa","bbbbb","cccccc","ddddddd","eeeeee","ffffff","gggggg","hhhhh"}
  6. local buttons = {}
  7.  
  8. local function update(self)
  9.     local numItems = #list
  10.     print ("DEBUG: nr. items " .. numItems)
  11.     FauxScrollFrame_Update(self, numItems, NUM_BUTTONS, BUTTON_HEIGHT)
  12.     local offset = FauxScrollFrame_GetOffset(self)
  13.     for line = 1, NUM_BUTTONS do
  14.         local lineplusoffset = line + offset
  15.         local button = buttons[line]
  16.         if lineplusoffset > numItems then
  17.             button:Hide()
  18.         else
  19.             button:SetText(list[lineplusoffset])
  20.             button:Show()
  21.         end
  22.     end
  23. end
  24.  
  25. local scrollFrame = CreateFrame("ScrollFrame", "MyFirstNotReallyScrollFrame", UIParent, "FauxScrollFrameTemplate")
  26. scrollFrame:SetWidth(BUTTON_WIDTH)
  27. scrollFrame:SetHeight(BUTTON_HEIGHT*6)
  28. scrollFrame:SetPoint("CENTER",UIParent)
  29. scrollFrame:EnableMouse(true)
  30. scrollFrame:SetMovable(true)
  31. scrollFrame:RegisterForDrag("LeftButton")
  32. scrollFrame:SetScript("OnDragStart", function(self) self:StartMoving() end)
  33. scrollFrame:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end)
  34. scrollFrame:Show()
  35. scrollFrame:SetClampedToScreen(true)
  36. scrollFrame:SetScript("OnVerticalScroll", function(self, offset)
  37.     FauxScrollFrame_OnVerticalScroll(self, offset, BUTTON_HEIGHT, update)
  38. end)
  39.  
  40. for i = 1, NUM_BUTTONS do
  41.     local button = CreateFrame("Button", nil, scrollFrame:GetParent())
  42.     if i == 1 then
  43.         button:SetPoint("TOP", scrollFrame)
  44.     else
  45.         button:SetPoint("TOP", buttons[i - 1], "BOTTOM")
  46.     end
  47.     button:SetNormalFontObject("GameFontNormal")
  48.     button:SetSize(BUTTON_WIDTH, BUTTON_HEIGHT)
  49.     button:SetText(list[i])
  50.     buttons[i] = button
  51. end
  52.  
  53.  
  54.  
  55. -- enabling the last line will make the slidebar disappears.
  56. -- print ("DEBUG: Force updating")
  57. -- update(scrollFrame)

Now I get the scrollframe with sliders but it is wrong. You can check the picture to see...
It doesn't cover the out of scrollframe part nor it scrolls using the slide.

Other thing: If I enable the manual update of the frame (last line) the sliders will disappears (!??!) :-)

Thanks again for any inputs/clues/tips :-)
Attached Thumbnails
Click image for larger version

Name:	img-001.png
Views:	960
Size:	49.1 KB
ID:	7563  
__________________
This is Unix-Land. In quiet nights, you can hear the Windows machines reboot.
  Reply With Quote
02-12-13, 10:00 AM   #11
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Good to hear.

This is all expected. The buttons are actually completely independant of the scroll frame and vice versa. They just happen to be anchored to it. For all the scroll frame knows, you could be simply printing different numbers in the update function instead of doing something with the buttons.

You have decided that 8 buttons be created (as per NUM_BUTTONS), and the size of the scroll frame is smaller than the total height of these. That's all there is to it. Again, the scroll frame is completely independent of the buttons, and has no idea how much screen space they take up. If you're using constants for the number of buttons and their height a simple solution would be:
Code:
scrollFrame:SetHeight(NUM_BUTTONS * BUTTON_HEIGHT)
which I just noticed you were nearly already doing, you just used 6 instead of 8 which NUM_BUTTONS was set to. This way the appropriate height will always be calculated when you change the amount and height of the buttons via the constants. At least, as long as the offset between each button is 0.

The scroll bar will always remain in its original state (visible and inactive) until you first call FauxScrollFrame_Update, which you do in the update function. The reason it disappears when you do so is that you have enough buttons that the entire list can be displayed without scrolling (you have 8 buttons and 8 items in the list). If you add one more item or remove one button, you will see that it works!
__________________
Grab your sword and fight the Horde!
  Reply With Quote
02-12-13, 10:00 AM   #12
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Try this example
http://wowprogramming.com/snippets/W...roll_frames_22

It does not make use of templates yet but it shows how to handle the ScrollChild.

Of course...using FauxTemplate is handling the ScrollChild quite differently I think.

*edit*

Got exactly what I was looking for.



Code will be coming soon.

I'm using a ScrollFrame with this template: "UIPanelScrollFrameTemplate" with a twist.

To bad I wanted a ScrollBar with this template: "UIPanelScrollBarTrimTemplate". The UIPanelScrollFrameTemplate only uses UIPanelScrollBarTemplate. So I just looked up the SetTexCoord for the scrollbar border and added it manually.

*edit*

Ok here is the code that does it:
http://code.google.com/p/rothui/sour...estScrollFrame

Thanks to templates there is actually veeery few code to write.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)

Last edited by zork : 02-12-13 at 01:26 PM.
  Reply With Quote
03-09-13, 03:50 AM   #13
Aanson
A Flamescale Wyrmkin
Join Date: Aug 2009
Posts: 124
Originally Posted by gmarco View Post
Hi all,
I prefer if possible to avoid this approach and so I am trying to find some links, addons, code to check how this can be implemented with the plain LUA api interface.

I have tried to convert the xml approach to lua code but I didn't succeded.
They there. I wrote a complete Scroll Frame example on another forum of this website that will provide you with all of the code you're after, and an explanation:

Tutorials & Other Helpful Info

I hope you find it as useful as was intended


Aanson
__________________
__________________
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Help on ScrollFrame with LUA

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