Example #1
0
	def describe_short(self):
		""" Used in macro editor """
		if self.count <= 1:
			return "%s %s" % (_("Tap"), ButtonAction.describe_button(self.button))
		if self.count == 2:
			return "%s %s" % (_("DblTap"), ButtonAction.describe_button(self.button))
		return "%s%s %s" % (self.count, _("-tap"), ButtonAction.describe_button(self.button))
    def load_circular_action(self, action):
        cbAxisOutput = self.builder.get_object("cbAxisOutput")
        btCircularAxis = self.builder.get_object("btCircularAxis")
        btCircularButton0 = self.builder.get_object("btCircularButton0")
        btCircularButton1 = self.builder.get_object("btCircularButton1")

        # Turn action into list of subactions (even if it's just single action)
        if isinstance(action.action, MultiAction):
            actions = action.action.actions
        else:
            actions = [action.action]

        # Parse that list
        self.circular_axis, self.circular_buttons = NoAction(), [None, None]
        for action in actions:
            if isinstance(action, ButtonAction):
                self.circular_buttons = [action.button, action.button2]
            else:
                self.circular_axis = action

        # Set labels
        b0, b1 = self.circular_buttons
        btCircularButton0.set_label(ButtonAction.describe_button(b0))
        btCircularButton1.set_label(ButtonAction.describe_button(b1))
        btCircularAxis.set_label(self.circular_axis.describe(Action.AC_PAD))

        self.set_cb(cbAxisOutput, "circular", 2)
Example #3
0
	def load_circular_action(self, action):
		cbAxisOutput = self.builder.get_object("cbAxisOutput")
		btCircularAxis = self.builder.get_object("btCircularAxis")
		btCircularButton0 = self.builder.get_object("btCircularButton0")
		btCircularButton1 = self.builder.get_object("btCircularButton1")
		
		# Turn action into list of subactions (even if it's just single action)
		if isinstance(action.action, MultiAction):
			actions = action.action.actions
		else:
			actions = [ action.action ]
		
		# Parse that list
		self.circular_axis, self.circular_buttons = NoAction(), [ None, None ]
		for action in actions:
			if isinstance(action, ButtonAction):
				self.circular_buttons = [ action.button, action.button2 ]
			else:
				self.circular_axis = action
		
		# Set labels
		b0, b1 = self.circular_buttons
		btCircularButton0.set_label(ButtonAction.describe_button(b0))
		btCircularButton1.set_label(ButtonAction.describe_button(b1))
		btCircularAxis.set_label(self.circular_axis.describe(Action.AC_PAD))
		
		self.set_cb(cbAxisOutput, "circular", 2)
Example #4
0
 def __init__(self, string):
     params = []
     shift = False
     for letter in string:
         if (letter >= 'a' and letter <= 'z') or (letter >= '0'
                                                  and letter <= '9'):
             if hasattr(Keys, ("KEY_" + letter).upper()):
                 if shift:
                     params.append(ReleaseAction(Keys.KEY_LEFTSHIFT))
                     shift = False
                 params.append(
                     ButtonAction(getattr(Keys, ("KEY_" + letter).upper())))
                 continue
         if letter == ' ':
             params.append(ButtonAction(Keys.KEY_SPACE))
             continue
         if letter >= 'A' and letter <= 'Z':
             if hasattr(Keys, "KEY_" + letter):
                 if not shift:
                     params.append(PressAction(Keys.KEY_LEFTSHIFT))
                     shift = True
                 params.append(ButtonAction(getattr(Keys, "KEY_" + letter)))
                 continue
         raise ValueError("Invalid character for type(): '%s'" % (letter, ))
     Macro.__init__(self, *params)
     self.letters = string
Example #5
0
 def on_key_grabbed(self, keys):
     """ Handles selecting key using "Grab the Key" dialog """
     action = ButtonAction(keys[0])
     if len(keys) > 1:
         actions = [ButtonAction(k) for k in keys]
         action = MultiAction(*actions)
     self.editor.set_action(action)
Example #6
0
	def button_release(self, mapper):
		if self._keep_pressed:
			self._keep_pressed = False
			if len(self._lst) > 0:
				# _rel_tap_press is still scheduled
				self._lst += [ False ]
			else:
				ButtonAction._button_release(mapper, self.button)
Example #7
0
 def apply_keys(self):
     """ Common part of on_*key_grabbed """
     keys = list(self.keys)
     action = ButtonAction(keys[0])
     if len(keys) > 1:
         actions = [ButtonAction(k) for k in keys]
         action = MultiAction(*actions)
     self.editor.set_action(action)
Example #8
0
    def release_virtual_buttons(self):
        """
		Called when daemon is killed or USB dongle is disconnected.
		Sends button release event for every virtual button that is still being
		pressed.
		"""
        to_release, self.pressed = self.pressed, {}
        for x in to_release:
            ButtonAction._button_release(self, x, True)
Example #9
0
	def release_virtual_buttons(self):
		"""
		Called when daemon is killed or USB dongle is disconnected.
		Sends button release event for every virtual button that is still being
		pressed.
		"""
		to_release, self.pressed = self.pressed, {}
		for x in to_release:
			ButtonAction._button_release(self, x, True)
	def test_cycle(self):
		"""
		Tests if Cycle can be converted to string and parsed back to
		same action.
		"""
		assert _parses_as_itself(Cycle(
			ButtonAction(Keys.BTN_LEFT),
			ButtonAction(Keys.BTN_RIGHT),
			ButtonAction(Keys.BTN_MIDDLE)
		))
	def test_repeat(self):
		"""
		Tests if Repeat can be converted to string and parsed back to
		same action.
		"""
		assert _parses_as_itself(Repeat(ButtonAction(Keys.BTN_LEFT)))
		assert _parses_as_itself(Repeat(Macro(
			ButtonAction(Keys.BTN_LEFT),
			ButtonAction(Keys.BTN_RIGHT),
			ButtonAction(Keys.BTN_MIDDLE)
		)))
Example #12
0
 def apply_keys(self, *a):
     """ Common part of on_*key_grabbed """
     cbToggle = self.builder.get_object("cbToggle")
     keys = list(sorted(self.keys, key=ButtonsComponent.modifiers_first))
     action = ButtonAction(keys[0])
     if len(keys) > 1:
         actions = [ButtonAction(k) for k in keys]
         action = MultiAction(*actions)
     if cbToggle.get_active():
         action = Cycle(PressAction(action), ReleaseAction(action))
     self.editor.set_action(action)
    def make_circular_action(self):
        """
		Constructs Circular Modifier
		"""
        if self.circular_axis and any(self.circular_buttons):
            return CircularModifier(
                MultiAction(self.circular_axis,
                            ButtonAction(*self.circular_buttons)))
        elif any(self.circular_buttons):
            return CircularModifier(ButtonAction(*self.circular_buttons))
        else:
            return CircularModifier(self.circular_axis)
Example #14
0
 def button_press(self, mapper):
     if self.button in mapper.pressed and mapper.pressed[self.button] > 0:
         # Uses scheduler to generate release-press-release-press sequence.
         self.lst = [
             ButtonAction._button_release,
             ButtonAction._button_press,
             ButtonAction._button_release,
             ButtonAction._button_press,
         ]
         self._rel_tap_press(mapper)
     else:
         ButtonAction._button_press(mapper, self.button)
         mapper.schedule(0, self._scheduled_release)
Example #15
0
	def button_press(self, mapper):
		if self.button in mapper.pressed and mapper.pressed[self.button] > 0:
			# Uses scheduler to generate release-press-release-press sequence.
			self.lst = [
				ButtonAction._button_release,
				ButtonAction._button_press,
				ButtonAction._button_release,
				ButtonAction._button_press,
			]
			self._rel_tap_press(mapper)
		else:
			ButtonAction._button_press(mapper, self.button)
			mapper.schedule(0, self._scheduled_release)
Example #16
0
	def update(self):
		cb = self.builder.get_object("cbActionType")
		key = cb.get_model().get_value(cb.get_active_iter(), 1)
		if key == "dpad8":
			# 8-way dpad
			self.editor.set_action(DPad8Action(*self.actions))
		elif key == "dpad":
			# 4-way dpad
			self.editor.set_action(DPadAction(*self.actions[0:4]))
		elif key == "wsad":
			# special case of 4-way dpad
			a = DPadAction(ButtonAction(Keys.KEY_W), ButtonAction(Keys.KEY_S),
				ButtonAction(Keys.KEY_A), ButtonAction(Keys.KEY_D))
			self.actions = [ NoAction() ] * 8
			self.editor.set_action(a)
			self.update_button_desc(a)
		elif key == "arrows":
			# special case of 4-way dpad
			a = DPadAction(ButtonAction(Keys.KEY_UP),
				ButtonAction(Keys.KEY_DOWN), ButtonAction(Keys.KEY_LEFT),
				ButtonAction(Keys.KEY_RIGHT))
			self.actions = [ NoAction() ] * 8
			self.editor.set_action(a)
			self.update_button_desc(a)
		else:
			# Menu
			self.on_cbMenus_changed()
Example #17
0
	def apply_keys(self, *a):
		""" Common part of on_*key_grabbed """
		cbToggle = self.builder.get_object("cbToggle")
		cbRepeat = self.builder.get_object("cbRepeat")
		keys = list(sorted(self.keys, key=ButtonsComponent.modifiers_first))
		action = ButtonAction(keys[0])
		if len(keys) > 1:
			actions = [ ButtonAction(k) for k in keys ]
			action = MultiAction(*actions)
		if cbRepeat.get_active():
			action = Macro(action)
			action.repeat = True
		elif cbToggle.get_active():
			action = Cycle(PressAction(action), ReleaseAction(action))
		self.editor.set_action(action)
Example #18
0
	def describe_short(self):
		""" Used in macro editor """
		if isinstance(self.action, ButtonAction):
			return self.action.describe_short()
		if isinstance(self.action, Keys):
			return ButtonAction.describe_button(self.action)
		return self.action.describe(Action.AC_BUTTON)
    def on_cbAxisOutput_changed(self, *a):
        cbAxisOutput = self.builder.get_object("cbAxisOutput")
        stActionData = self.builder.get_object("stActionData")
        key = cbAxisOutput.get_model().get_value(
            cbAxisOutput.get_active_iter(), 2)
        if key == 'area':
            stActionData.set_visible_child(self.builder.get_object("grArea"))
            action = self.make_area_action()
            self.update_osd_area(action)
        elif key == "button":
            stActionData.set_visible_child(self.builder.get_object("vbButton"))
            self.button = self.button or ButtonAction(Keys.BTN_GAMEPAD)
            action = self.button
        elif key == "circular":
            stActionData.set_visible_child(
                self.builder.get_object("grCircular"))
            action = self.make_circular_action()
        elif key == 'mouse':
            stActionData.set_visible_child(self.builder.get_object("vbMose"))
            if not self._recursing and self.editor.friction == 0:
                # When switching to mouse, enable trackball by default
                self.editor.friction = 10
            action = self.make_mouse_action()
        else:
            stActionData.set_visible_child(self.builder.get_object("nothing"))
            action = cbAxisOutput.get_model().get_value(
                cbAxisOutput.get_active_iter(), 0)
            action = self.parser.restart(action).parse()
            self.update_osd_area(None)

        self.editor.set_action(action)
Example #20
0
    def test_name(self):
        """
		Tests if NameModifier can be converted to string and parsed
		back to same.
		"""
        assert _parses_as_itself(
            NameModifier("Not A Button", ButtonAction(Keys.KEY_A)))
Example #21
0
    def on_cbAxisOutput_changed(self, *a):
        cbAxisOutput = self.builder.get_object("cbAxisOutput")
        stActionData = self.builder.get_object("stActionData")
        key = cbAxisOutput.get_model().get_value(
            cbAxisOutput.get_active_iter(), 2)
        if key == 'area':
            stActionData.set_visible_child(self.builder.get_object("grArea"))
            action = self.make_area_action()
            self.update_osd_area(action)
        elif key == "button":
            stActionData.set_visible_child(self.builder.get_object("vbButton"))
            self.button = self.button or ButtonAction(Keys.BTN_GAMEPAD)
            action = self.button
        elif key == "circular":
            stActionData.set_visible_child(
                self.builder.get_object("grCircular"))
            action = self.make_circular_action()
        elif key == 'trackball':
            stActionData.set_visible_child(
                self.builder.get_object("vbTrackball"))
            action = self.make_trackball_action()
        else:
            stActionData.set_visible_child(self.builder.get_object("nothing"))
            action = cbAxisOutput.get_model().get_value(
                cbAxisOutput.get_active_iter(), 0)
            action = self.parser.restart(action).parse()
            self.update_osd_area(None)

        self.editor.set_action(action)
Example #22
0
 def on_buttonaction_type_change(self, cb, data):
     if cb.get_active() == 0:
         data[0] = ButtonAction(data[0].button)
     elif cb.get_active() == 1:
         data[0] = PressAction(data[0].button)
     else:
         data[0] = ReleaseAction(data[0].button)
     self.update_action_field()
Example #23
0
 def on_buttonaction_type_change(self, cb, i, action_data):
     if cb.get_active() == 0:
         self.actions[i] = action_data._replace(
             action=ButtonAction(action_data.action))
     elif cb.get_active() == 1:
         self.actions[i] = action_data._replace(
             action=PressAction(action_data.action))
     else:
         self.actions[i] = action_data._replace(
             action=ReleaseAction(action_data.action))
     self.update_action_field()
Example #24
0
    def send(self):
        levels = []
        half_level = int(
            self.builder.get_object("sclPartialLevel").get_value() + 0.1)
        full_level = int(
            self.builder.get_object("sclFullLevel").get_value() + 0.1)

        if half_level != TRIGGER_HALF or full_level != TRIGGER_CLICK:
            levels.append(half_level)
        if full_level != TRIGGER_CLICK:
            levels.append(full_level)

        self.editor.set_action(ButtonAction(self.half, self.full, *levels))
Example #25
0
	def on_ok(self, action):
		if isinstance(action.strip(), AreaAction):
			# Kinda hacky way to set action on LPAD press or RPAD press
			# when user selects Mouse Area as ouput and checks
			# 'Pressing the Pad Clicks' checkbox
			side = getattr(SCButtons, self.editor.get_id())
			clicks = self.pressing_pad_clicks()
			
			if self.builder.get_object("cbAreaClickEnabled").get_active():
				if not clicks:
					# Turn pad press into mouse clicks
					self.app.set_action(self.app.current, side, ButtonAction(Keys.BTN_LEFT))
			else:
				if clicks:
					# Clear action created above if checkbox is uncheck
					self.app.set_action(self.app.current, side, NoAction())
Example #26
0
	def __init__(self, *parameters):
		Action.__init__(self, *parameters)
		self.actions = []
		self.repeat = False
		self._active = False
		self._current = None
		self._release = None
		for p in parameters:
			if type(p) == float and len(self.actions):
				self.actions[-1].delay_after = p
			elif isinstance(p, Macro):
				self.actions += p.actions
			elif isinstance(p, Action):
				self.actions.append(p)
			else:
				self.actions.append(ButtonAction(p))
Example #27
0
 def update(self):
     cb = self.builder.get_object("cbActionType")
     scl = self.builder.get_object("sclDiagonalRange")
     key = cb.get_model().get_value(cb.get_active_iter(), 1)
     if key == "dpad8":
         # 8-way dpad
         self.editor.set_action(DPad8Action(scl.get_value(), *self.actions))
     elif key == "dpad":
         # 4-way dpad
         self.editor.set_action(
             DPadAction(scl.get_value(), *self.actions[0:4]))
     elif key == "wsad":
         # special case of 4-way dpad
         a = DPadAction(scl.get_value(), ButtonAction(Keys.KEY_W),
                        ButtonAction(Keys.KEY_S), ButtonAction(Keys.KEY_A),
                        ButtonAction(Keys.KEY_D))
         self.actions = [NoAction()] * 8
         self.editor.set_action(a)
         self.update_button_desc(a)
     elif key == "arrows":
         # special case of 4-way dpad
         a = DPadAction(scl.get_value(), ButtonAction(Keys.KEY_UP),
                        ButtonAction(Keys.KEY_DOWN),
                        ButtonAction(Keys.KEY_LEFT),
                        ButtonAction(Keys.KEY_RIGHT))
         self.actions = [NoAction()] * 8
         self.editor.set_action(a)
         self.update_button_desc(a)
     elif key == "actual_dpad":
         # maps to dpad as real gamepad usually has
         a = DPadAction(scl.get_value(), HatUpAction(Axes.ABS_HAT0Y),
                        HatDownAction(Axes.ABS_HAT0Y),
                        HatLeftAction(Axes.ABS_HAT0X),
                        HatRightAction(Axes.ABS_HAT0X))
         self.actions = [NoAction()] * 8
         self.editor.set_action(a)
         self.update_button_desc(a)
     else:
         # Menu
         self.on_cbMenus_changed()
Example #28
0
	def _rel_tap_press(self, mapper):
		if not self.button in mapper.pressed or mapper.pressed[self.button] < self.COUNTER_VAL:
			# Something else tried to _release_ button in meanwhile, bail out
			mapper.pressed[self.button] = 1
			ButtonAction._button_release(mapper, self.button)
			return self._bailout()
		elif mapper.pressed[self.button] > self.COUNTER_VAL:
			# Something else pressed button in meanwhile, bail out
			mapper.pressed[self.button] = 1
			return self._bailout()
		
		a, self._lst = self._lst[0], self._lst[1:]
		if a:
			mapper.pressed[self.button] = 0
			ButtonAction._button_press(mapper, self.button)
		else:
			mapper.pressed[self.button] = 1
			ButtonAction._button_release(mapper, self.button)
		if len(self._lst):
			mapper.pressed[self.button] = self.COUNTER_VAL
			mapper.schedule(self.PAUSE, self._rel_tap_press)
Example #29
0
    def parse_action(self, lst_or_str, button=None):
        """
		Parses action from vdf file. a_string can be either string or list of
		strings, in which case MultiAction is returned.
		
		Returns Action instance or ParseError if action is not recognized.
		"""
        if type(lst_or_str) == list:
            return MultiAction.make(
                *[self.parse_action(x) for x in lst_or_str])
        # Split string into binding type, name and parameters
        binding, params = lst_or_str.split(" ", 1)
        if "," in params:
            params, name = params.split(",", 1)
        else:
            params, name = params, None
        params = params.split(" ")
        if name:
            name = name.strip()
        # Return apropriate Action for binding type
        if binding in ("key_press", "mouse_button"):
            if binding == "mouse_button":
                b = VDFProfile.convert_button_name(params[0])
            else:
                b = VDFProfile.convert_key_name(params[0])
            return ButtonAction(b).set_name(name)
        elif binding == "xinput_button":
            # Special cases, as dpad is apparently button on Windows
            b = params[0].strip().lower()
            if b == "dpad_up":
                return HatUpAction(Axes.ABS_HAT0Y)
            elif b == "dpad_down":
                return HatDownAction(Axes.ABS_HAT0Y)
            elif b == "dpad_left":
                return HatLeftAction(Axes.ABS_HAT0X)
            elif b == "dpad_right":
                return HatRightAction(Axes.ABS_HAT0X)
            elif b == "trigger_left":
                return AxisAction(Axes.ABS_Z)
            elif b == "trigger_right":
                return AxisAction(Axes.ABS_RZ)
            else:
                b = VDFProfile.convert_button_name(b)
                return ButtonAction(b).set_name(name)
        elif binding in ("mode_shift"):
            if button is None:
                log.warning("Ignoring modeshift assigned to no button: '%s'" %
                            (lst_or_str, ))
                return NoAction()
            if button not in VDFProfile.BUTTON_TO_BUTTON:
                log.warning(
                    "Ignoring modeshift assigned to unknown button: '%s'" %
                    (button, ))
                return NoAction()
            self.modeshift_buttons[VDFProfile.BUTTON_TO_BUTTON[button]] = (
                params[1], params[0])
            return NoAction()
        elif binding in ("controller_action"):
            if params[0] == "CHANGE_PRESET":
                id = int(params[1]) - 1
                cpa = ChangeProfileAction("action_set:%s" % (id, ))
                self.action_set_switches.add(cpa)
                return cpa

            log.warning("Ignoring controller_action '%s' binding" %
                        (params[0], ))
            return NoAction()
        elif binding == "mouse_wheel":
            if params[0].lower() == "scroll_down":
                return MouseAction(Rels.REL_WHEEL, -1)
            else:
                return MouseAction(Rels.REL_WHEEL, 1)
        else:
            raise ParseError("Unknown binding: '%s'" % (binding, ))
Example #30
0
 def grab_action(self, button, cb):
     b = SimpleChooser(self.app, "buttons", cb)
     b.set_title(_("Select Button"))
     b.hide_axes()
     b.display_action(Action.AC_BUTTON, ButtonAction(button))
     b.show(self.editor.window)
Example #31
0
	def button_press(self, mapper):
		ButtonAction._button_release(mapper, self.button)
Example #32
0
	def _scheduled_release(self, mapper):
		ButtonAction._button_release(mapper, self.button)
Example #33
0
	def button_press(self, mapper):
		ButtonAction._button_release(mapper, self.button)
Example #34
0
    def _convert(self, from_version):
        """ Performs conversion from older profile version """
        if from_version < 1:
            from scc.modifiers import ModeModifier
            # Add 'display Default.menu if center button is held' for old profiles
            c = self.buttons[SCButtons.C]
            if not c:
                # Nothing set to C button
                self.buttons[SCButtons.C] = HoldModifier(
                    MenuAction("Default.menu"),
                    normalaction=MenuAction("Default.menu"))
            elif hasattr(c, "holdaction") and c.holdaction:
                # Already set to something, don't overwrite it
                pass
            elif c.to_string().startswith("OSK."):
                # Special case, don't touch this either
                pass
            else:
                self.buttons[SCButtons.C] = HoldModifier(
                    MenuAction("Default.menu"),
                    normalaction=self.buttons[SCButtons.C])
        if from_version < 1.1:
            # Convert old scrolling wheel to new representation
            from scc.modifiers import FeedbackModifier, BallModifier
            from scc.actions import MouseAction, XYAction
            from scc.uinput import Rels
            iswheelaction = (
                lambda x: isinstance(x, MouseAction) and x.parameters[0] in
                (Rels.REL_HWHEEL, Rels.REL_WHEEL))
            for p in (Profile.LEFT, Profile.RIGHT):
                a, feedback = self.pads[p], None
                if isinstance(a, FeedbackModifier):
                    feedback = a.haptic.get_position()
                    a = a.action
                if isinstance(a, XYAction):
                    if iswheelaction(a.x) or iswheelaction(a.y):
                        n = BallModifier(XYAction(a.x, a.y))
                        if feedback is not None:
                            n = FeedbackModifier(feedback, 4096, 16, n)
                        self.pads[p] = n
                        log.info("Converted %s to %s", a.to_string(),
                                 n.to_string())
        if from_version < 1.2:
            # Convert old trigger settings that were done with ButtonAction
            # to new TriggerAction
            from scc.constants import TRIGGER_HALF, TRIGGER_MAX, TRIGGER_CLICK
            from scc.actions import ButtonAction, TriggerAction, MultiAction
            from scc.uinput import Keys
            for p in (Profile.LEFT, Profile.RIGHT):
                if isinstance(self.triggers[p], ButtonAction):
                    buttons, numbers = [], []
                    n = None
                    # There were one or two keys and zero to two numeric
                    # parameters for old button action
                    for param in self.triggers[p].parameters:
                        if param in Keys:
                            buttons.append(param)
                        elif type(param) in (int, float):
                            numbers.append(int(param))
                    if len(numbers) == 0:
                        # Trigger range was not specified, assume defaults
                        numbers = (TRIGGER_HALF, TRIGGER_CLICK)
                    elif len(numbers) == 1:
                        # Only lower range was specified, add default upper range
                        numbers.append(TRIGGER_CLICK)
                    if len(buttons) == 1:
                        # If only one button was set, trigger should work like
                        # one big button
                        n = TriggerAction(numbers[0], ButtonAction(buttons[0]))
                    elif len(buttons) == 2:
                        # Both buttons were set
                        n = MultiAction(
                            TriggerAction(numbers[0], numbers[1],
                                          ButtonAction(buttons[0])),
                            TriggerAction(numbers[1], TRIGGER_MAX,
                                          ButtonAction(buttons[1])))

                    if n:
                        log.info("Converted %s to %s",
                                 self.triggers[p].to_string(), n.to_string())
                        self.triggers[p] = n
Example #35
0
	def area_action_selected(self, area, action):
		if area:
			self.set_active_area(area)
		if self.full:
			action = MultiAction(ButtonAction(None, self.full), action)
		self.editor.set_action(action)
Example #36
0
 def _scheduled_release(self, mapper):
     ButtonAction._button_release(mapper, self.button)