I have created a scroll box, however it may not be very helpful, the code is very messy. I used Moguri’s bgui, so if you’re unfamiliar with that, the code is probably going to be even more confusing.
In my example, I have a list for the actual text objects and a list for the text that needs to go into the text objects.
Anyway, you want to check out lib\editor.py, the drag_scroll_box() is the one of interest.
The lines:
mouse = bge.logic.mouse
pos = list(mouse.position)
pos[0] *= bge.render.getWindowWidth()
pos[1] = bge.render.getWindowHeight() - (bge.render.getWindowHeight() * pos[1])
y = pos[1] - self.scroll_bar.position[1]
y /= self.scroll_bar.size[1]
c_pos = self.scroll_box.position[1] # current position
c_pos -= self.scroll_bar.position[1]
c_pos /= self.scroll_bar.size[1]
should be ignored, they are simply normalising position values.
The next line
difference = y - self.file_scroll_box_click_pos
describes how far the scroll bar has moved since it was first clicked. The ‘self.file_scroll_box_click_pos’ variable describes the position of the scroll box from the previous frame, it is used to calculate how far its traveled since.
self.scroll_box._update_position([1,min(1,13/self.file_total_files)], [0, max(0, min(1-min(1,13/self.file_total_files),c_pos+difference))])
self.file_scroll_box_click_pos = y
These lines update the display of the scroll box and the old position variable for next frame. Your code for changing the scroll box’s position may be different because the lines are represented from bottom to top in python and top to bottom graphically (like I said, messy!). The 13 is there because it is the number of lines in the scroll box.
incriment = (1-min(1,13/self.file_total_files))/(self.file_total_files-13)
if incriment == 0:
return
I was actually a little stumped looking at this, I had forgotten what it is for (note to self, more comments ^^). It describes how a line translates into the scroll bar, i.e how many pixels the scroll box has to move before all the lines are moved and as such, if it is 0, no line movement is needed and the function can return.
c_item = self.file_total_files - int(c_pos/incriment) - 13
if c_item != self.file_view:
self.update_scroll_box_items(c_item)
The above determines which item is to be displayed at the top (c_item, an index for the text object list). Again, the -13 is there because my lines are upside down in code (and there is 13 of them). self.file_view is the item which is currently at the top of the scroll box. self.update_scroll_box_items() is a function which re-orders the scroll box, with c_item being the one at the top. That function is as follows:
def update_scroll_box_items(self, c_item):
for n in range(13):
if c_item + n < len(self.folders):
text = self.folders[c_item+n]
self.file_icons[n] = bgui.Image(self.file_rows[12-n], 'file_icon_'+str(n), bge.logic.expandPath("//textures\\folder.png"), size=[20/600, 20/25],
pos=[80/600, 0], options=bgui.BGUI_DEFAULT|bgui.BGUI_CENTERY)
elif c_item + n < self.file_total_files:
text = self.files[c_item + n - len(self.folders)]
self.file_icons[n] = bgui.Image(self.file_rows[12-n], 'file_icon_'+str(n), bge.logic.expandPath("//textures\\file.png"), size=[20/600, 20/25],
pos=[80/600, 0], options=bgui.BGUI_DEFAULT|bgui.BGUI_CENTERY)
else:
text = ''
self.file_items[n] = bgui.Label(self.file_rows[12-n], 'file_item_'+str(n), text, font=bge.logic.expandPath("//fonts\\MankSans.ttf"), pt_size=20, color=(0,0,0,1),
pos=[100/600, 0], options=bgui.BGUI_DEFAULT|bgui.BGUI_CENTERY)
self.file_view = c_item
What you need to take away from that function is the c_item + n for the index of the lines list, not simply n. The rest of the code fills in all the text objects based on the c_item + n index.
I hope I didn’t confuse you too much, I also hope the steps I have described help you to create a scroll box regardless if you use the bgui or not.
My example file is here: (2.54)
https://docs.google.com/leaf?id=0B3Vo1hyFBl0KY2ZkOGNjMWMtNDI3Yy00NTQzLWI0YmMtN2E3MGE0M2ExZTA3&hl=en
Run it a select ‘Open’, its a file browser which is still a bit buggy but its a scroll box nonetheless.