I made a DirectScrollBar with custom thumb and inc/dec buttons. Instead of just supplying a single image for each button, I used the egg-texture-cards program to create an egg file from 4 different raw images so that the buttons would have a different appearance for hover and click.
The raw images are all 16x16 png files. Here is the normal (non-hover, non-clicked) image for the thumb:
It has a 1 pixel white border which is hard to see against this white page background.
I call egg-texture-cards like this:
egg-texture-cards -o scrollbar_left_button.egg -g '-8,8,-8,8' scrollbar_left_normal.png scrollbar_left_clicked.png scrollbar_left_rollover.png scrollbar_left_disabled.png
egg-texture-cards -o scrollbar_right_button.egg -g '-8,8,-8,8' scrollbar_right_normal.png scrollbar_right_clicked.png scrollbar_right_rollover.png scrollbar_right_disabled.png
egg-texture-cards -o scrollbar_thumb_button.egg -g '-8,8,-8,8' scrollbar_thumb_normal.png scrollbar_thumb_clicked.png scrollbar_thumb_rollover.png scrollbar_thumb_disabled.png
Then, I use this code to create a scroll bar:
import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import DirectScrollBar
from direct.gui.DirectGuiGlobals import VERTICAL
from direct.gui.DirectGuiGlobals import HORIZONTAL
class World(DirectObject):
def __init__(self):
self.accept( 'window-event', self.windowEventHandler)
self.button_size = 16
self.half_button_size = self.button_size / 2
self.button_padding = self.button_size / 4
self.button_radius = self.half_button_size + self.button_padding
self.three_button_radii = 3 * self.button_radius
self.scrollbar_indent = 4 * self.button_radius + self.button_padding
self.scrollbar_width = 10
self.half_scrollbar_width = self.scrollbar_width / 2
self.slider_indent = 2 * self.button_radius + self.button_padding
scrollbar_thumb_maps = loader.loadModel("scrollbar_thumb_button")
self.scrollbar_thumb_geom = (scrollbar_thumb_maps.find('**/scrollbar_thumb_normal'),
scrollbar_thumb_maps.find('**/scrollbar_thumb_clicked'),
scrollbar_thumb_maps.find('**/scrollbar_thumb_rollover'),
scrollbar_thumb_maps.find('**/scrollbar_thumb_disabled'))
scrollbar_left_maps = loader.loadModel("scrollbar_left_button")
self.scrollbar_left_button_geom = (scrollbar_left_maps.find('**/scrollbar_left_normal'),
scrollbar_left_maps.find('**/scrollbar_left_clicked'),
scrollbar_left_maps.find('**/scrollbar_left_rollover'),
scrollbar_left_maps.find('**/scrollbar_left_disabled'))
scrollbar_right_maps = loader.loadModel("scrollbar_right_button")
self.scrollbar_right_button_geom = (scrollbar_right_maps.find('**/scrollbar_right_normal'),
scrollbar_right_maps.find('**/scrollbar_right_clicked'),
scrollbar_right_maps.find('**/scrollbar_right_rollover'),
scrollbar_right_maps.find('**/scrollbar_right_disabled'))
self.scrollbar = DirectScrollBar(value = 0.5, command = self.handle_scrollbar,
manageButtons = True,
scrollSize = .001,
pageSize = .1,
thumb_relief = None,
decButton_relief = None,
incButton_relief = None,
thumb_pressEffect = 1,
thumb_geom=self.scrollbar_thumb_geom,
decButton_geom=self.scrollbar_left_button_geom,
incButton_geom=self.scrollbar_right_button_geom,
resizeThumb=False)
self.scrollbar.reparentTo(pixel2d)
def handle_scrollbar(self):
print self.scrollbar['value']
def windowEventHandler( self, window=None ):
if window is not None: # window is none if panda3d is not started
wp = window.getProperties()
wpXSize = wp.getXSize()
wpYSize = wp.getYSize()
self.scrollbar['frameSize'] = (-.5*wpXSize + self.scrollbar_indent, .5*wpXSize - self.scrollbar_indent, -self.half_scrollbar_width, self.half_scrollbar_width)
self.scrollbar.setPos(.5*wpXSize, 0, -self.button_radius)
w = World()
run()
The untouched window then looks like this:
Here is an enlarged view of the thumb:
After clicking on the right arrow button (the increment button, at the right end of the scroll bar), the window looks like this:
Again, here is an enlarged view of the thumb:
See how the left edge of the thumb appears dim or clipped?
After clicking on the right arrow button for a second time, the window looks like this:
The enlarged view of the thumb now looks like this:
See how now the right edge is clipped, or dim.
But after clicking on the right arrow button for a third time, everything seems back to normal. Here is the window after 3 clicks:
The enlarged thumb looks like this now:
It seems back to normal.
That is one problem. The second problem is that after a horizontal resize, my inc/dec buttons just disappear:
I should mention that dragging the thumb along the scrollbar does not seem to leave the thumb in a state that looks clipped, IF it was not in such a state to begin with. However, if it was clipped at the start of the drag, it will look clipped at the end of the drag.
I’m guessing that clicking on the inc/dec buttons causes the thumb to translate by the amount specified by the “scrollSize” parameter to DirectScrollBar, and this translation distance does not match up with pixel widths, causing the thumb to end up “between” pixels. After a few clicks, maybe the fractional pixel translation amounts add up to a whole pixel, and the thumb is aligned again.
If this is the case, is there anything I could do in my python code to avoid these artefacts?
Thank you.