Property definitions

gamnit $ DPad :: defaultinit
# Directional pad with up to 4 buttons
#
# Assumes that each pad is manipulated by at max a single pointer.
class DPad
	super RoundControl

	# Event names for the keys, in order of top, left, down and right
	var names: Array[String]

	# Show the up button
	var show_up = true is writable

	# Show the down button
	var show_down = true is writable

	# Show the left button
	var show_left = true is writable

	# Show the right button
	var show_right = true is writable

	redef fun radius do return 200.0

	redef fun contains(ui_pos)
	do
		if show_down then return super(new Point[Float](ui_pos.x+0.0, ui_pos.y-100.0))
		return super
	end

	redef fun hit(event, ui_pos)
	do
		var display = app.display
		if display == null then return false

		var dx = ui_pos.x - center.x
		var dy = ui_pos.y - center.y
		if show_down then dy -= 100.0

		# Angle (with 0.0 on the right) to index in WASD (0 -> W/up)
		var indexes = new Set[Int]
		var ao = atan2(dy, dx)
		ao -= pi/4.0

		# Look for 2 angles so 2 buttons can be pressed at the same time
		for da in once [-pi/8.0, pi/8.0] do
			var a = ao+da
			while a < 0.0 do a += pi*2.0
			while a > 2.0*pi do a -= pi*2.0
			var index = (a * 2.0 / pi).floor.to_i
			if index < 0 then index += 4
			indexes.add index
		end

		var shows = [show_up, show_left, show_down, show_right]
		var new_down_names = new Set[String]
		for index in indexes do
			# Don't trigger events for hidden buttons/directions
			if not shows[index] then continue

			var name = names[index]
			# Simulate event
			var e = new VirtualGamepadEvent(name)
			e.is_down = event.pressed
			app.accept_event e

			if event.pressed then new_down_names.add name
		end

		# Depress released directions
		for name in down_names do
			if not new_down_names.has(name) then
				var e = new VirtualGamepadEvent(name)
				e.is_down = false
				app.accept_event e
			end
		end

		down_names = new_down_names

		return true
	end

	redef fun sprites
	do
		var dy = 0.0
		if show_down then dy = 100.0

		var sprites = new Array[Sprite]

		# Interactive buttons
		if show_up then sprites.add new Sprite(app.gamepad_spritesheet.dpad_up,
			center.offset(   0.0, 100.0+dy, 0.0))
		if show_left then sprites.add new Sprite(app.gamepad_spritesheet.dpad_left,
			center.offset(-100.0,   0.0+dy, 0.0))
		if show_right then sprites.add new Sprite(app.gamepad_spritesheet.dpad_right,
			center.offset( 100.0,   0.0+dy, 0.0))
		if show_down then sprites.add new Sprite(app.gamepad_spritesheet.dpad_down,
			center.offset(   0.0,-100.0+dy, 0.0))

		# Non-interactive joystick background
		var back = new Sprite(app.gamepad_spritesheet.joystick_back,
			center.offset(0.0, 0.0+dy, -1.0)) # In the back
		back.draw_order = -1
		sprites.add back

		# Non-interactive handle in the bottom
		if not show_down then sprites.add new Sprite(app.gamepad_spritesheet.joystick_down,
			center.offset(0.0, -100.0+dy,  0.0))

		return sprites
	end
end
lib/gamnit/virtual_gamepad/virtual_gamepad.nit:314,1--425,3