[BUG]Slider Bar Click Behavior

The only way I can see to give the slider the behavior you want would be to remove the track listener, and script the movements yourself, but that gets somewhat complex. It's possible that creating a custom slider would be simpler.

To remove the listener, add this to the slider's propertyChange event handler:

# Runs once and only once at run time
# Won't run in the designer unless preview mode is active prior to the window being opened.
if event.propertyName == 'componentRunning':

	# Iterate through the various mouse listeners, and surgically remove the track listener
	for listener in event.source.mouseListeners:
		if 'SynthTrackListener' in listener.__class__.__name__:
			event.source.removeMouseListener(listener)

Moving the knob around and setting values will require quite a bit of scaling in multiple event handlers, so I would set up a library script for this, or add a custom method to the component like this one here:


#Custom method on the slider component with parameters: value, originalMin, originalMax, scaledMin, scaledMax 
#def getScaledValue(self, value, originalMin, originalMax, scaledMin, scaledMax):
	"""
	Arguments:
		self: A reference to the[...]
	"""
	originalRange = originalMax - originalMin
	
	# Cast one of the variables to float, or the rules of integer division will evaluate this as zero
	percentage = (value - originalMin)/float(originalRange)
	scaledRange = scaledMax - scaledMin
	
	# Cast the scaled value back to an int, and return it
	return int((percentage * scaledRange) + scaledMin)

Use the mousePressed event handler to determine whether or not the slider knob should be dragged. This can be conveyed to the mouseDragged event handler by adding a custom property to the component called "dragEnabled"

# Written for the mousePressed event handler
# Do not allow dragging if the component is disabled
if event.source.enabled:
	from java.awt import Rectangle
	knobRadius = 30
	if event.source.inverted and event.source.horizontal:
		valuePosition = event.source.getScaledValue(event.source.value, event.source.minimum, event.source.maximum, 0 , event.source.width)
		knobBounds = Rectangle(event.source.width - valuePosition - knobRadius, event.source.height / 2 - knobRadius, 2 * knobRadius, 2 * knobRadius)
	elif event.source.inverted and not event.source.horizontal:
		valuePosition = event.source.getScaledValue(event.source.value, event.source.minimum, event.source.maximum, 0 , event.source.height)
		knobBounds = Rectangle(event.source.width / 2 - knobRadius, valuePosition - knobRadius, 2 * knobRadius, 2 * knobRadius)
	elif event.source.horizontal:
		valuePosition = event.source.getScaledValue(event.source.value, event.source.minimum, event.source.maximum, 0 , event.source.width)
		knobBounds = Rectangle(valuePosition - knobRadius, event.source.height / 2 - knobRadius , 2 * knobRadius, 2 * knobRadius)
	else:
		valuePosition = event.source.getScaledValue(event.source.value, event.source.minimum, event.source.maximum, 0 , event.source.height)
		knobBounds = Rectangle(event.source.width / 2 - knobRadius, event.source.height - valuePosition - knobRadius, 2 * knobRadius, 2 * knobRadius)
	
	if knobBounds.contains(event.x, event.y):
		event.source.dragEnabled = True
		
	event.source.parent.getComponent('Paintable Canvas').leftClick = True

When the user drags the slider, and the dragEnabled custom property has been set during the mouse pressed event, control the knob position with this script:

# Written for the mouse dragged event handler
# Enabled from the mousePressed event handler
if event.source.dragEnabled:
	# There are four ways the slider can be configured that will change where the knob is positioned within the component in relationship to the slider value,
	# ...so they all have to be accounted for to ensure the calculation comes out correct
	if event.source.inverted and event.source.horizontal:
		newValue = event.source.getScaledValue(event.source.width - event.x, 0, event.source.width, event.source.minimum, event.source.maximum)
	elif event.source.inverted and not event.source.horizontal:
		newValue = event.source.getScaledValue(event.y, 0, event.source.height, event.source.minimum, event.source.maximum)
	elif event.source.horizontal: # horizontal and not inverted 
		newValue = event.source.getScaledValue(event.x, 0, event.source.width, event.source.minimum, event.source.maximum)
	else: # not inverted and not horizontal
		newValue = event.source.getScaledValue(event.source.height - event.y, 0, event.source.height, event.source.minimum, event.source.maximum)
	
	# Prevent the calculated value from exceding the bounds of the component
	if newValue < event.source.minimum:
		newValue = event.source.minimum
	elif newValue > event.source.maximum:
		newValue = event.source.maximum
	
	# When a the slider's value property changes, the knob automatically moves to the appropriate position
	event.source.value = newValue

Finally, when the user releases the mouse button, disable slider movements with the mouse released event handler:

# Written for the mouseReleased event handler,
event.source.dragEnabled = False

Result:
Presentation1

Edit: Note that this approach relies on the componentRunning event handler, so it won't work in the designer unless preview mode is already running when the window is opened.

1 Like