Ejemplo n.º 1
0
	def select_gyro_button(self, item):
		""" Just sets combobox value """
		cb = self.builder.get_object("cbGyroButton")
		rvSoftLevel = self.builder.get_object("rvSoftLevel")
		sclSoftLevel = self.builder.get_object("sclSoftLevel")
		lblSoftLevel = self.builder.get_object("lblSoftLevel")
		model = cb.get_model()
		self._recursing = True
		button = None
		if isinstance(item, RangeOP):
			button = nameof(item.what)
			sclSoftLevel.set_value(item.value)
			rvSoftLevel.set_reveal_child(True)
			if item.what == STICK:
				lblSoftLevel.set_label(_("Stick deadzone"))
			else:
				lblSoftLevel.set_label(_("Trigger Pull Level"))
		elif item is not None:
			button = nameof(item.name)
		for row in model:
			if button == row[0] and row[1] != None:
				cb.set_active_iter(row.iter)
				self._recursing = False
				return
		self._recursing = False
Ejemplo n.º 2
0
	def _mod_to_string(self, params, multiline, pad):
		""" Adds action at end of params list and generates string """
		if multiline:
			childstr = self.action.to_string(True, pad + 2)
			if len(params) > 0:
				return "%s%s(%s,%s%s)" % (
					" " * pad,
					self.COMMAND,
					", ".join([ nameof(s) for s in params ]),
					'\n' if '\n' in childstr else ' ',
					childstr
				)
			return "%s%s(%s)" % ( " " * pad, self.COMMAND, childstr.strip() )
		childstr = self.action.to_string(False, pad)
		if len(params) > 0:
			return "%s%s(%s, %s)" % (
				" " * pad,
				self.COMMAND,
				", ".join([ nameof(s) for s in params ]),
				childstr
			)

		return "%s%s(%s)" % (
			" " * pad,
			self.COMMAND,
			childstr
		)
Ejemplo n.º 3
0
	def to_string(self, multiline=False, pad=0):
		if multiline:
			rv = [ (" " * pad) + "mode(" ]
			for check in self.mods:
				a_str = NameModifier.unstrip(self.mods[check]).to_string(True).split("\n")
				a_str[0] = (" " * pad) + "  " + (nameof(check) + ",").ljust(11) + a_str[0]	# Key has to be one of SCButtons
				for i in xrange(1, len(a_str)):
					a_str[i] = (" " * pad) + "  " + a_str[i]
				a_str[-1] = a_str[-1] + ","
				rv += a_str
			if self.default is not None:
				a_str = [
					(" " * pad) + "  " + x
					for x in NameModifier.unstrip(self.default).to_string(True).split("\n")
				]
				rv += a_str
			if rv[-1][-1] == ",":
				rv[-1] = rv[-1][0:-1]
			rv += [ (" " * pad) + ")" ]
			return "\n".join(rv)
		else:
			rv = [ ]
			for check in self.mods:
				rv += [ nameof(check), NameModifier.unstrip(self.mods[check]).to_string(False) ]
			if self.default is not None:
				rv += [ NameModifier.unstrip(self.default).to_string(False) ]
			return "mode(" + ", ".join(rv) + ")"
Ejemplo n.º 4
0
	def load(self):
		if AEComponent.load(self):
			markup = ""
			if self.editor.get_mode() == Action.AC_PAD:
				markup = MARKUP_PAD
			elif self.editor.get_mode() == Action.AC_STICK:
				markup = MARKUP_STICK
			elif self.editor.get_mode() == Action.AC_GYRO:
				markup = MARKUP_GYRO
			elif self.editor.get_mode() == Action.AC_TRIGGER:
				markup = MARKUP_TRIGGER
			else:
				markup = MARKUP_BUTTON
			
			long_names = {
				'LPAD' : _("Left Pad"),
				'RPAD' : _("Right Pad"),
				'LGRIP' : _("Left Grip"),
				'RGRIP' : _("Right Grip"),
				'LB' : _("Left Bumper"),
				'RB' : _("Right Bumper"),
				'LEFT' : _("Left Trigger"),
				'RIGHT' : _("Right Trigger"),
				'STICK' : _("Stick"),
			}
			
			markup = markup % {
				'what' : long_names.get(nameof(self.editor.get_id()),
								nameof(self.editor.get_id()).title())
			}
			self.builder.get_object("lblMarkup").set_markup(markup.strip(" \r\n\t"))
			return True
Ejemplo n.º 5
0
	def load_menu_data(self, action):
		if isinstance(action, PositionModifier):
			# Load menu position modifier, if used
			x, y = action.position
			self.builder.get_object("cbMenuPosX").set_active(0 if x >= 0 else 1)
			self.builder.get_object("cbMenuPosY").set_active(0 if y >= 0 else 1)
			self.builder.get_object("spMenuPosX").set_value(abs(x))
			self.builder.get_object("spMenuPosY").set_value(abs(y))
			action = action.action
		
		self._current_menu = action.menu_id
		cbm = self.builder.get_object("cbMenuType")
		self.set_cb(cbm, self.menu_class_to_key(action), 1)
		
		if self.builder.get_object("rvMenuSize"):
			spMenuSize = self.builder.get_object("spMenuSize")
			if self.update_size_display(action):
				size = spMenuSize.get_adjustment().set_value(action.size)
		
		cbControlWith = self.builder.get_object("cbControlWith")
		cbConfirmWith = self.builder.get_object("cbConfirmWith")
		cbCancelWith = self.builder.get_object("cbCancelWith")
		cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
		cbMenuConfirmWithClick = self.builder.get_object("cbMenuConfirmWithClick")
		cbMenuAutoCancel = self.builder.get_object("cbMenuAutoCancel")
		if cbControlWith:
			self.set_cb(cbControlWith, nameof(action.control_with), 1)
		
		cow = action.confirm_with
		caw = action.cancel_with
		
		if cbConfirmWith:
			if cow == SAME and cbMenuAutoConfirm:
				cbMenuAutoConfirm.set_active(True)
				cbConfirmWith.set_sensitive(False)
			elif cbMenuConfirmWithClick and cow == self.get_default_confirm():
				cbMenuConfirmWithClick.set_active(True)
				cbConfirmWith.set_sensitive(False)
			else:
				if cbMenuAutoConfirm:
					cbMenuAutoConfirm.set_active(False)
				if cbMenuConfirmWithClick:
					cbMenuAutoConfirm.set_active(False)
				cbConfirmWith.set_sensitive(True)
				self.set_cb(cbConfirmWith, nameof(cow), 1)
		
		if cbCancelWith:
			if caw == SAME and cbMenuAutoCancel:
				cbMenuAutoCancel.set_active(True)
				cbCancelWith.set_sensitive(False)
			else:
				if cbMenuAutoCancel:
					cbMenuAutoCancel.set_active(False)
				self.set_cb(cbCancelWith, nameof(caw), 1)
		
		self.on_cbMenus_changed()
Ejemplo n.º 6
0
	def on_cursor_motion(self, trash, event):
		# self.icon.get_allocation().x + self.icon.get_allocation().width	# yields nonsense
		ix2 = 74
		# Check if cursor is placed on icon
		if event.x < ix2:
			what = {
				Profile.LPAD : LEFT,
				Profile.RPAD : RIGHT,
				Profile.CPAD : nameof(SCButtons.CPADPRESS),
				Profile.STICK : nameof(SCButtons.STICKPRESS),
			}[self.name]
			self.app.hilight(what)
			self.over_icon = True
		else:
			self.app.hilight(self.name)
			self.over_icon = False
Ejemplo n.º 7
0
	def __str__(self):
		rv = [ ]
		for check in self.mods:
			rv += [ nameof(check), self.mods[check] ]
		if self.default is not None:
			rv += [ self.default ]
		return "<Modifier '%s', %s>" % (self.COMMAND, rv)
Ejemplo n.º 8
0
	def _fill_button_images(self, buttons):
		e = self.edit()
		SVGEditor.update_parents(e)
		target = SVGEditor.get_element(e, "controller")
		target_x, target_y = SVGEditor.get_translation(target)
		for i in xrange(len(ControllerImage.BUTTONS_WITH_IMAGES)):
			b = nameof(ControllerImage.BUTTONS_WITH_IMAGES[i])
			try:
				elm = SVGEditor.get_element(e, "AREA_%s" % (b,))
				if elm is None:
					log.warning("Area for button %s not found", b)
					continue
				x, y = SVGEditor.get_translation(elm)
				scale = 1.0
				if "scc-button-scale" in elm.attrib:
					w, h = SVGEditor.get_size(elm)
					scale = float(elm.attrib['scc-button-scale'])
					tw, th = w * scale, h * scale
					if scale < 1.0:
						x += (w - tw) * 0.5
						y += (h - th) * 0.5
					else:
						x -= (tw - w) * 0.25
						y -= (th - h) * 0.25
				path = os.path.join(self.app.imagepath, "button-images",
					"%s.svg" % (buttons[i], ))
				img = SVGEditor.get_element(SVGEditor.load_from_file(path), "button")
				img.attrib["transform"] = "translate(%s, %s) scale(%s)" % (
					x - target_x, y - target_y, scale)
				img.attrib["id"] = b
				SVGEditor.add_element(target, img)
			except Exception, err:
				log.warning("Failed to add image for button %s", b)
				log.exception(err)
Ejemplo n.º 9
0
	def add(self, icon, context, action):
		if not action: return LineCollection()
		if isinstance(action, MultiAction):
			if not action.is_key_combination():
				return LineCollection([
					self.add(icon, context, child)
					for child in action.actions
				])
		elif isinstance(action, ModeModifier):
			lines = [ self.add(icon, context, action.default) ]
			for x in action.mods:
				lines.append( self.add(nameof(x), context, action.mods[x])
						.add_icon(icon) )
			return LineCollection(*lines)
		elif isinstance(action, DoubleclickModifier):
			lines = []
			if action.normalaction:
				lines.append( self.add(icon, context, action.normalaction) )
			if action.action:
				lines.append( self.add("DOUBLECLICK", context, action.action)
						.add_icon(icon) )
			if action.holdaction:
				lines.append( self.add("HOLD", context, action.holdaction)
						.add_icon(icon) )
			return LineCollection(*lines)
		
		action = action.strip()
		if isinstance(action, MenuAction):
			if self.name == "bcs" and action.menu_id == "Default.menu":
				# Special case, this action is expected in every profile,
				# so there is no need to draw it here
				return LineCollection()
		elif isinstance(action, DPadAction):
			return LineCollection(
				self.add("DPAD_UP",    Action.AC_BUTTON, action.actions[0]),
				self.add("DPAD_DOWN",  Action.AC_BUTTON, action.actions[1]),
				self.add("DPAD_LEFT",  Action.AC_BUTTON, action.actions[2]),
				self.add("DPAD_RIGHT", Action.AC_BUTTON, action.actions[3])
			)
		elif isinstance(action, XYAction):
			if isinstance(action.x, MouseAction) and isinstance(action.y, MouseAction):
				if action.x.get_axis() in (Rels.REL_HWHEEL, Rels.REL_WHEEL):
					# Special case, pad bound to wheel
					line = Line(icon, _("Mouse Wheel"))
					self.lines.append(line)
					return line	
			if isinstance(action.x, AxisAction) and isinstance(action.y, AxisAction):
				if action.x.axis and action.y.axis:
					line = Line(icon, action.x.describe(Action.AC_BUTTON))
					self.lines.append(line)
					return line
			return LineCollection(
				self.add("AXISX",  Action.AC_BUTTON, action.x),
				self.add("AXISY",  Action.AC_BUTTON, action.y)
			)
		line = Line(icon, action.describe(context))
		self.lines.append(line)
		return line
Ejemplo n.º 10
0
	def set_mapping(self, keycode, what):
		parent = self.parent
		
		if isinstance(what, AxisData) and what in parent._mappings.values():
			for c in parent._mappings.keys():
				if parent._mappings[c] == what:
					del parent._mappings[c]
		
		parent._mappings[keycode] = what
		log.debug("Reassigned %s to %s", keycode, what)
		
		if nameof(what) in parent._unassigned:
			parent._unassigned.remove(nameof(what))
			parent.unhilight(nameof(what))
		
		self.parent.generate_unassigned()
		self.parent.generate_raw_data()
		self.cancel()
Ejemplo n.º 11
0
	def to_string(self, multiline=False, pad=0):
		rv = "%s%s(" % (" " * pad, self.COMMAND)
		if self.confirm_with != DEFAULT:
			rv += "%s, " % (nameof(self.confirm_with),)
			if self.cancel_with != DEFAULT:
				rv += "%s, " % (nameof(self.cancel_with),)
		rv += "'%s', " % (self.text.encode('string_escape'),)
		if multiline:
			rv += "\n%s" % (" " * (pad + 2))
		for option in self.options:
			rv += "%s, " % (option.to_string(False),)
			if multiline:
				rv += "\n%s" % (" " * (pad + 2))
		
		rv = rv.strip("\n ,")
		if multiline:
			rv += "\n)"
		else:
			rv += ")"
		return rv
    def get_button_name(config, button):
        """
		As get_button_icon, but returns icon name instead of filename.
		"""
        name = nameof(button)
        try:
            index = BUTTON_ORDER.index(button)
            name = ControllerManager.DEFAULT_ICONS[index]
            name = config['gui']['buttons'][index]
        except:
            pass
        return name
Ejemplo n.º 13
0
	def button_press(self, mapper):
		if not self.show_with_release:
			confirm_with = self.confirm_with
			cancel_with = self.cancel_with
			args = [ mapper ]
			if confirm_with == SAME:
				confirm_with = mapper.get_pressed_button() or DEFAULT
			elif confirm_with == DEFAULT:
				confirm_with = DEFAULT
			if cancel_with == DEFAULT:
				cancel_with = DEFAULT
			if nameof(self.control_with) in (LEFT, RIGHT):
				args += [ '--use-cursor' ]
			args += [
				'--control-with', nameof(self.control_with),
				'-x', str(self.x), '-y', str(self.y),
				'--size', str(self.size),
				'--confirm-with', nameof(confirm_with),
				'--cancel-with', nameof(cancel_with)
			]
			self.execute(*args)
Ejemplo n.º 14
0
	def on_clearb_clicked(self, trash, index, button):
		grActions = self.action_widgets[index][0]
		cbButtonChooser = self.builder.get_object("cbButtonChooser")
		model = cbButtonChooser.get_model()
		# Remove requested action from the list
		for i in xrange(0, len(self.actions[index])):
			if self.actions[index][i][0] == button:
				button, action, l, b, clearb = self.actions[index][i]
				for w in (l, b, clearb): grActions.remove(w)
				del self.actions[index][i]
				break
		# Move everything after that action one position up
		# - remove it
		for j in xrange(i, len(self.actions[index])):
			button, action, l, b, clearb = self.actions[index][j]
			for w in (l, b, clearb): grActions.remove(w)
		# - add it again
		for j in xrange(i, len(self.actions[index])):
			button, action, l, b, clearb = self.actions[index][j]
			grActions.attach(l,			0, j + 1, 1, 1)
			grActions.attach(b,			1, j + 1, 1, 1)
			grActions.attach(clearb,	2, j + 1, 1, 1)
		# Regenereate combobox with removed button added back to it
		# - Store acive item from in combobox
		active, i, index = None, 0, -1
		try:
			active = model.get_value(cbButtonChooser.get_active_iter(), 0)
		except: pass
		# Clear entire combobox
		model.clear()
		# Fill it again
		for button, text in self.BUTTONS:
			model.append(( None if button is None else nameof(button), text ))
			if button is not None:
				if nameof(button) == active:
					index = i
			i += 1
		# Reselect formely active item
		if index >= 0:
			cbButtonChooser.set_active(index)
Ejemplo n.º 15
0
 def button_press(self, mapper):
     if not self.show_with_release:
         if self.confirm_with == SAME:
             confirm_with = mapper.get_pressed_button(
             ) or self.DEFAULT_CONFIRM
             x, y = self.position
             self.execute(mapper,
                          '--control-with', nameof(self.control_with), '-x',
                          str(self.x), '-y', str(self.y), '--use-cursor',
                          '--confirm-with', confirm_with.name,
                          '--cancel-with', self.cancel_with.name)
         else:
             self.execute(mapper, '-x', str(self.x), '-y', str(self.y))
Ejemplo n.º 16
0
    def _fill_button_chooser(self, *a):
        cbButtonChooser = self.builder.get_object("cbButtonChooser")
        model = cbButtonChooser.get_model()
        model.clear()
        for item, text in self.BUTTONS:
            if any([x[0] == item for x in self.actions[self.current_page]]):
                # Skip already added buttons
                continue
            if type(item) in (str, unicode):
                # Special case for soft pull items
                button = getattr(SCButtons, item.split(" ")[-1])
                if any([(isinstance(x, RangeOP) and x.what == button)
                        for x in self.actions[self.current_page]]):
                    # Skip already added soft pulls
                    continue

            if item == SCButtons.STICKPRESS:
                if self.id == nameof(SCButtons.LPAD):
                    # Controller cannot handle pressing stick and lpad at once
                    continue
            model.append((None if item is None else nameof(item), text))
        cbButtonChooser.set_active(0)
Ejemplo n.º 17
0
 def whole(self, mapper, x, y, what, *params):
     if x == 0 and y == 0:
         # Sent when pad is released - don't display menu then
         return
     if self.haptic:
         params = list(params) + [
             "--feedback-amplitude",
             str(self.haptic.get_amplitude())
         ]
     if what in (LEFT, RIGHT):
         confirm_with = self.confirm_with
         cancel_with = self.cancel_with
         if what == LEFT:
             if confirm_with == DEFAULT: confirm_with = SCButtons.LPAD
             if cancel_with == DEFAULT: cancel_with = SCButtons.LPADTOUCH
         elif what == RIGHT:
             if confirm_with == DEFAULT: confirm_with = SCButtons.RPAD
             if cancel_with == DEFAULT: cancel_with = SCButtons.RPADTOUCH
         else:
             # Stick
             if confirm_with == DEFAULT: confirm_with = SCButtons.STICKPRESS
             if cancel_with == DEFAULT: cancel_with = SCButtons.B
         if not mapper.was_pressed(cancel_with):
             self.execute(mapper, '--control-with', what, '-x', str(self.x),
                          '-y', str(self.y), '--use-cursor', '--size',
                          str(self.size), '--confirm-with',
                          nameof(confirm_with), '--cancel-with',
                          nameof(cancel_with), *params)
     if what == STICK:
         # Special case, menu is displayed only if is moved enought
         distance = sqrt(x * x + y * y)
         if self._stick_distance < MenuAction.MIN_STICK_DISTANCE and distance > MenuAction.MIN_STICK_DISTANCE:
             self.execute(mapper,
                          '--control-with', STICK, '-x', str(self.x), '-y',
                          str(self.y), '--use-cursor', '--size',
                          str(self.size), '--confirm-with', "STICKPRESS",
                          '--cancel-with', STICK, *params)
         self._stick_distance = distance
Ejemplo n.º 18
0
 def button_release(self, mapper):
     confirm_with = self.confirm_with
     cancel_with = self.cancel_with
     args = [mapper]
     if confirm_with == DEFAULT:
         confirm_with = MenuAction.DEFAULT_CONFIRM
     if cancel_with == DEFAULT:
         cancel_with = MenuAction.DEFAULT_CANCEL
     args += [
         '-x',
         str(self.x),
         '-y',
         str(self.y),
         '--confirm-with',
         nameof(confirm_with),
         '--cancel-with',
         nameof(cancel_with),
         '--text',
         self.text,
     ]
     for x in self.options:
         args.append(x)
     self.execute(*args)
Ejemplo n.º 19
0
	def _fill_button_chooser(self, *a):
		cbButtonChooser = self.builder.get_object("cbButtonChooser")
		model = cbButtonChooser.get_model()
		model.clear()
		for button, text in self.BUTTONS:
			if any([ True for x in self.actions[self.current_page] if x[0] == button ]):
				# Skip already added buttons
				continue
			if button == SCButtons.STICKPRESS:
				if self.id == nameof(SCButtons.LPAD):
					# Controller cannot handle pressing stick and lpad at once
					continue
			model.append(( None if button is None else button.name, text ))
		cbButtonChooser.set_active(0)
Ejemplo n.º 20
0
	def load_menu_data(self, action):
		if isinstance(action, PositionModifier):
			# Load menu position modifier, if used
			x, y = action.position
			self.builder.get_object("cbMenuPosX").set_active(0 if x >= 0 else 1)
			self.builder.get_object("cbMenuPosY").set_active(0 if y >= 0 else 1)
			self.builder.get_object("spMenuPosX").set_value(abs(x))
			self.builder.get_object("spMenuPosY").set_value(abs(y))
			action = action.action
		
		self._current_menu = action.menu_id
		cbm = self.builder.get_object("cbMenuType")
		self.set_cb(cbm, self.menu_class_to_key(action), 1)
		
		cbControlWith = self.builder.get_object("cbControlWith")
		cbConfirmWith = self.builder.get_object("cbConfirmWith")
		cbCancelWith = self.builder.get_object("cbCancelWith")
		cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
		if cbControlWith:
			self.set_cb(cbControlWith, nameof(action.control_with), 1)
			self.set_cb(cbConfirmWith, nameof(action.confirm_with), 1)
			self.set_cb(cbCancelWith, nameof(action.cancel_with), 1)
		if cbMenuAutoConfirm:
			cbMenuAutoConfirm.set_active(action.confirm_with == SAME)
Ejemplo n.º 21
0
    def set_input(self, id, action, mode=None):
        btDefault = self.builder.get_object("btDefault")
        lblPressAlone = self.builder.get_object("lblPressAlone")
        cbHoldFeedback = self.builder.get_object("cbHoldFeedback")
        sclHoldFeedback = self.builder.get_object("sclHoldFeedback")

        self.id = id
        self._fill_button_chooser()

        if id in STICKS:
            lblPressAlone.set_label(_("(no button pressed)"))
            self.mode = mode = mode or Action.AC_STICK
        elif id in PADS:
            lblPressAlone.set_label(_("(no button pressed)"))
            self.mode = mode = mode or Action.AC_PAD
        else:
            lblPressAlone.set_label(_("(pressed alone)"))
            self.mode = mode = mode or Action.AC_BUTTON

        self.set_title("Modeshift for %s" %
                       (nameof(id) if id in SCButtons else str(id), ))

        if isinstance(action, FeedbackModifier):
            cbHoldFeedback.set_active(True)
            sclHoldFeedback.set_value(action.haptic.get_amplitude())
            action = action.action
        else:
            cbHoldFeedback.set_active(False)
            sclHoldFeedback.set_value(512)

        if isinstance(action, ModeModifier):
            self._load_modemod(0, action)
            self._set_nomod_button(0, action.default)
            self._set_nomod_button(1, NoAction())
            self._set_nomod_button(2, NoAction())
        elif isinstance(action, DoubleclickModifier):  # includes HoldModifier
            self._set_nomod_button(0, action.normalaction)
            self._set_nomod_button(1, action.holdaction)
            self._set_nomod_button(2, action.action)
        self.builder.get_object("adjTime").set_value(action.timeout)

        if mode == Action.AC_OSK:
            # This is kinda bad, but allowing Custom Editor
            # from OSK editor is in TODO
            self.builder.get_object("btCustomActionEditor").set_visible(False)
        if mode != Action.AC_BUTTON:
            for w in ("vbHold", "vbDoubleClick", "lblHold", "lblDoubleClick"):
                self.builder.get_object(w).set_sensitive(False)
Ejemplo n.º 22
0
	def add(self, icon, context, action):
		if not action: return LineCollection()
		if isinstance(action, ModeModifier):
			lines = [ self.add(icon, context, action.default) ]
			for x in action.mods:
				lines.append( self.add(nameof(x), context, action.mods[x])
						.add_icon(icon) )
			return LineCollection(*lines)
		elif isinstance(action, DoubleclickModifier):
			lines = []
			if action.normalaction:
				lines.append( self.add(icon, context, action.normalaction) )
			if action.action:
				lines.append( self.add("DOUBLECLICK", context, action.action)
						.add_icon(icon) )
			if action.holdaction:
				lines.append( self.add("HOLD", context, action.holdaction)
						.add_icon(icon) )
			return LineCollection(*lines)
		
		action = action.strip()
		if isinstance(action, MenuAction):
			if self.name == "bcs" and action.menu_id == "Default.menu":
				# Special case, this action is expected in every profile,
				# so there is no need to draw it here
				return LineCollection()
		elif isinstance(action, DPadAction):
			return LineCollection(
				self.add("DPAD_UP",    Action.AC_BUTTON, action.actions[0]),
				self.add("DPAD_DOWN",  Action.AC_BUTTON, action.actions[1]),
				self.add("DPAD_LEFT",  Action.AC_BUTTON, action.actions[2]),
				self.add("DPAD_RIGHT", Action.AC_BUTTON, action.actions[3])
			)
		elif isinstance(action, XYAction):
			if isinstance(action.x, MouseAction) and isinstance(action.y, MouseAction):
				if action.x.get_axis() in (Rels.REL_HWHEEL, Rels.REL_WHEEL):
					# Special case, pad bound to wheel
					line = Line(icon, _("Mouse Wheel"))
					self.lines.append(line)
					return line	
			return LineCollection(
				self.add("AXISX",  Action.AC_BUTTON, action.x),
				self.add("AXISY",  Action.AC_BUTTON, action.y)
			)
		line = Line(icon, action.describe(context))
		self.lines.append(line)
		return line
Ejemplo n.º 23
0
def fill_buttons(cb):
	cb.set_row_separator_func( lambda model, iter : model.get_value(iter, 1) is None )
	model = cb.get_model()
	for button, text in GyroActionComponent.BUTTONS:
		model.append(( None if button is None else nameof(button), text ))	
	cb.set_active(0)
Ejemplo n.º 24
0
    def _parse_parameter(self):
        """ Parses single parameter """
        t = self._next_token()
        while t.type == TokenType.NEWLINE or t.value == "\n":
            if not self._tokens_left():
                raise ParseError("Expected parameter at end of string")
            t = self._next_token()

        if t.type == TokenType.NAME:
            # Constant or action used as parameter
            if self._tokens_left() and self._peek_token(
            ).type == TokenType.OP and self._peek_token().value == '(':
                # Action used as parameter
                self.index -= 1  # go step back and reparse as action
                parameter = self._parse_action()
            elif self._tokens_left() and t.value in Action.ALL and type(
                    Action.ALL[
                        t.value]) == dict and self._peek_token().value == '.':
                # SOMETHING.Action used as parameter
                self.index -= 1  # go step back and reparse as action
                parameter = self._parse_action()
            else:
                # Constant
                if not t.value in ActionParser.CONSTS:
                    raise ParseError(
                        "Expected parameter, got '%s' which is not defined" %
                        (t.value, ))
                parameter = ActionParser.CONSTS[t.value]

            # Check for dots
            while self._tokens_left() and self._peek_token(
            ).type == TokenType.OP and self._peek_token().value == '.':
                self._next_token()
                if not self._tokens_left():
                    raise ParseError("Expected NAME after '.'")

                t = self._next_token()
                if not hasattr(parameter, t.value):
                    raise ParseError("%s has no attribute '%s'" % (
                        parameter,
                        t.value,
                    ))
                parameter = getattr(parameter, t.value)

            # Check for ranges (<, >, <=, >=)
            if self._tokens_left() and self._peek_token().type == TokenType.OP:
                if self._peek_token().value in RangeOP.OPS:
                    op = self._next_token().value
                    # TODO: Maybe other axes
                    if parameter not in (STICK, SCButtons.LT, SCButtons.RT,
                                         SCButtons.X, SCButtons.Y):
                        raise ParseError("'%s' is not trigger nor axis" %
                                         (nameof(parameter), ))
                    if not self._tokens_left():
                        raise ParseError("Excepted number after '%s'" % (op, ))
                    try:
                        number = float(self._next_token().value)
                    except ValueError:
                        raise ParseError("Excepted number after '%s'" % (op, ))
                    parameter = RangeOP(parameter, op, number)

            return parameter

        if t.type == TokenType.OP and t.value == "-":
            if not self._tokens_left(
            ) or self._peek_token().type != TokenType.NUMBER:
                raise ParseError("Expected number after '-'")
            return -self._parse_number()

        if t.type == TokenType.NUMBER:
            self.index -= 1
            return self._parse_number()

        if t.type == TokenType.STRING:
            return t.value[1:-1].decode('string_escape')

        raise ParseError("Expected parameter, got '%s'" % (t.value, ))
Ejemplo n.º 25
0
	def set_input(self, id, action, mode=None):
		"""
		Setups action editor for editing specified input.
		Mode (buttton/axis/trigger...) is either provided or chosen based on id.
		Also sets title, but that can be overriden by calling set_title after.
		"""
		self.id = id
		if id in SCButtons or mode in (Action.AC_MENU, Action.AC_BUTTON):
			if id in PRESSABLE:
				self.set_title(_("%s Press") % (nameof(id),))
			elif id in SCButtons:
				self.set_title(nameof(id),)
			self._set_mode(action, mode or Action.AC_BUTTON)
			self.hide_sensitivity(0, 1, 2)
			self.hide_rotation()
			self.hide_hide_enable_deadzones()
			self.hide_require_click()
			self.set_action(action)
		elif id in TRIGGERS:
			self.set_title(_("%s Trigger") % (id,))
			self._set_mode(action, mode or Action.AC_TRIGGER)
			self.hide_modifiers()
			self.set_action(action)
			self.hide_macro()
		elif id in STICKS:
			self.set_title(_("Stick"))
			self._set_mode(action, mode or Action.AC_STICK)
			self.hide_sensitivity(2) # Z only
			self.hide_require_click()
			self.hide_osd()
			self.set_action(action)
			self.hide_macro()
			self.id = Profile.STICK
		elif id in GYROS:
			self.set_title(_("Gyro"))
			self._set_mode(action, mode or Action.AC_GYRO)
			self.set_action(action)
			self.hide_rotation()
			self.hide_require_click()
			self.hide_hide_enable_deadzones()
			self.hide_osd()
			self.hide_macro()
			self.hide_modeshift()
			self.id = Profile.GYRO
		elif id in PADS:
			self._set_mode(action, mode or Action.AC_PAD)
			self.hide_sensitivity(2) # Z only
			self.set_action(action)
			self.hide_osd()
			self.hide_macro()
			if id == "LPAD":
				self.set_title(_("Left Pad"))
			else:
				self.set_title(_("Right Pad"))
		if mode == Action.AC_OSK:
			self.hide_osd()
			self.hide_name()
			self.hide_macro()
			self.hide_modeshift()
			self.hide_rotation()
		elif mode == Action.AC_MENU:
			self.hide_modeshift()
			self.hide_macro()
from scc.actions import Action, NoAction, MouseAction, MultiAction, RangeOP
from scc.actions import GyroAction, GyroAbsAction, MouseAbsAction
from scc.special_actions import CemuHookAction
from scc.modifiers import ModeModifier, SensitivityModifier
from scc.uinput import Axes, Rels
from scc.constants import SCButtons, STICK, YAW, ROLL
from scc.gui.parser import GuiActionParser
from scc.gui.ae import AEComponent
from scc.tools import nameof

import logging, re

log = logging.getLogger("AE.GyroAction")

__all__ = ['GyroActionComponent']
TRIGGERS = (nameof(SCButtons.LT), nameof(SCButtons.RT))


class GyroActionComponent(AEComponent):
    GLADE = "ae/gyro_action.glade"
    NAME = "gyro_action"
    CTXS = Action.AC_GYRO
    PRIORITY = 3

    BUTTONS = (  # in order as displayed in combobox
        (None, _('Always Active')),
        (None, None),
        (SCButtons.LT, _('Left Trigger')),
        (SCButtons.RT, _('Right Trigger')),
        (SCButtons.LB, _('Left Bumper')),
        (SCButtons.RB, _('Right Bumper')),
Ejemplo n.º 27
0
def fill_buttons(cb):
	cb.set_row_separator_func( lambda model, iter : model.get_value(iter, 1) is None )
	model = cb.get_model()
	for button, text in GyroActionComponent.BUTTONS:
		model.append(( None if button is None else nameof(button), text ))	
	cb.set_active(0)
Ejemplo n.º 28
0
from scc.tools import _

from scc.actions import Action, NoAction, MouseAction, MultiAction, RangeOP
from scc.actions import GyroAction, GyroAbsAction, MouseAbsAction
from scc.modifiers import ModeModifier, SensitivityModifier
from scc.uinput import Axes, Rels
from scc.constants import SCButtons, STICK, YAW, ROLL
from scc.gui.parser import GuiActionParser
from scc.gui.ae import AEComponent
from scc.tools import nameof

import logging, re
log = logging.getLogger("AE.GyroAction")

__all__ = [ 'GyroActionComponent' ]
TRIGGERS = ( nameof(SCButtons.LT), nameof(SCButtons.RT) )


class GyroActionComponent(AEComponent):
	GLADE = "ae/gyro_action.glade"
	NAME = "gyro_action"
	CTXS = Action.AC_GYRO
	PRIORITY = 3
	
	BUTTONS = (	# in order as displayed in combobox
		(None,					_('Always Active')),
		(None, None),
		(SCButtons.LT,			_('Left Trigger') ),
		(SCButtons.RT,			_('Right Trigger') ),
		(SCButtons.LB,			_('Left Bumper') ),
		(SCButtons.RB,			_('Right Bumper') ),
Ejemplo n.º 29
0
 def encode(self):
     rv = Modifier.encode(self)
     pars = self.strip_defaults()
     pars[0] = nameof(pars[0])
     rv[FeedbackModifier.COMMAND] = pars
     return rv
Ejemplo n.º 30
0
	def encode(self):
		rv = Modifier.encode(self)
		pars = self.strip_defaults()
		pars[0] = nameof(pars[0])
		rv[FeedbackModifier.COMMAND] = pars
		return rv
Ejemplo n.º 31
0
	def set_input(self, id, action, mode=None):
		"""
		Setups action editor for editing specified input.
		Mode (buttton/axis/trigger...) is either provided or chosen based on id.
		Also sets title, but that can be overriden by calling set_title after.
		"""
		self.id = id
		if id in SCButtons or mode in (Action.AC_MENU, Action.AC_BUTTON):
			if id in PRESSABLE:
				self.set_title(_("%s Press") % (nameof(id),))
			elif id in SCButtons:
				self.set_title(nameof(id),)
			self._set_mode(action, mode or Action.AC_BUTTON)
			self.hide_sensitivity(0, 1, 2)
			self.hide_enable_feedback()
			self.hide_hide_enable_deadzones()
			self.hide_require_click()
			self.set_action(action)
		elif id in TRIGGERS:
			self.set_title(_("%s Trigger") % (id,))
			self._set_mode(action, mode or Action.AC_TRIGGER)
			self.hide_sensitivity(1, 2) # YZ
			self.hide_require_click()
			self.hide_hide_enable_deadzones()
			self.hide_osd()
			self.set_action(action)
			self.hide_macro()
		elif id in STICKS:
			self.set_title(_("Stick"))
			self._set_mode(action, mode or Action.AC_STICK)
			self.hide_sensitivity(2) # Z only
			self.hide_require_click()
			self.hide_osd()
			self.set_action(action)
			self.hide_macro()
			self.id = Profile.STICK
		elif id in GYROS:
			self.set_title(_("Gyro"))
			self._set_mode(action, mode or Action.AC_GYRO)
			self.set_action(action)
			self.hide_require_click()
			self.hide_hide_enable_deadzones()
			self.hide_osd()
			self.hide_macro()
			self.hide_modeshift()
			self.id = Profile.GYRO
		elif id in PADS:
			self._set_mode(action, mode or Action.AC_PAD)
			self.hide_sensitivity(2) # Z only
			self.set_action(action)
			self.hide_osd()
			self.hide_macro()
			if id == "LPAD":
				self.set_title(_("Left Pad"))
			else:
				self.set_title(_("Right Pad"))
		if mode == Action.AC_OSK:
			self.hide_osd()
			self.hide_name()
			self.hide_macro()
			self.hide_modeshift()
		elif mode == Action.AC_MENU:
			self.hide_modeshift()
			self.hide_macro()
Ejemplo n.º 32
0
    def load_menu_data(self, action):
        if isinstance(action, PositionModifier):
            # Load menu position modifier, if used
            x, y = action.position
            self.builder.get_object("cbMenuPosX").set_active(
                0 if x >= 0 else 1)
            self.builder.get_object("cbMenuPosY").set_active(
                0 if y >= 0 else 1)
            self.builder.get_object("spMenuPosX").set_value(abs(x))
            self.builder.get_object("spMenuPosY").set_value(abs(y))
            action = action.action

        self._current_menu = action.menu_id
        cbm = self.builder.get_object("cbMenuType")
        self.set_cb(cbm, self.menu_class_to_key(action), 1)

        if self.builder.get_object("rvMenuSize"):
            spMenuSize = self.builder.get_object("spMenuSize")
            if self.update_size_display(action):
                size = spMenuSize.get_adjustment().set_value(action.size)

        cbControlWith = self.builder.get_object("cbControlWith")
        cbConfirmWith = self.builder.get_object("cbConfirmWith")
        cbCancelWith = self.builder.get_object("cbCancelWith")
        cbMenuAutoConfirm = self.builder.get_object("cbMenuAutoConfirm")
        cbMenuConfirmWithClick = self.builder.get_object(
            "cbMenuConfirmWithClick")
        cbMenuAutoCancel = self.builder.get_object("cbMenuAutoCancel")
        if cbControlWith:
            self.set_cb(cbControlWith, nameof(action.control_with), 1)

        cow = action.confirm_with
        caw = action.cancel_with
        if cow == DEFAULT: cow = self.get_default_confirm()
        if caw == DEFAULT: caw = self.get_default_cancel()

        if cbConfirmWith:
            if cow == SAME and cbMenuAutoConfirm:
                cbMenuAutoConfirm.set_active(True)
                cbConfirmWith.set_sensitive(False)
            elif cbMenuConfirmWithClick and cow == self.get_default_confirm():
                cbMenuConfirmWithClick.set_active(True)
                cbConfirmWith.set_sensitive(False)
            else:
                if cbMenuAutoConfirm:
                    cbMenuAutoConfirm.set_active(False)
                if cbMenuConfirmWithClick:
                    cbMenuAutoConfirm.set_active(False)
                cbConfirmWith.set_sensitive(True)
                self.set_cb(cbConfirmWith, nameof(cow), 1)

        if cbCancelWith:
            if caw == SAME and cbMenuAutoCancel:
                cbMenuAutoCancel.set_active(True)
                cbCancelWith.set_sensitive(False)
            else:
                if cbMenuAutoCancel:
                    cbMenuAutoCancel.set_active(False)
                self.set_cb(cbCancelWith, nameof(caw), 1)

        self.on_cbMenus_changed()
Ejemplo n.º 33
0
class ControllerImage(SVGWidget):
    DEFAULT = "sc"
    BUTTONS_WITH_IMAGES = (SCButtons.A, SCButtons.B, SCButtons.X, SCButtons.Y,
                           SCButtons.BACK, SCButtons.C, SCButtons.START)

    DEFAULT_AXES = (
        # Shared between DS4 and Steam Controller
        "stick_x",
        "stick_y",
        "lpad_x",
        "lpad_x",
        "rpad_y",
        "rpad_y",
        "ltrig",
        "rtrig",
    )

    DEFAULT_BUTTONS = [nameof(x) for x in BUTTONS_WITH_IMAGES] + [
        # Used only by Steam Controller
        nameof(SCButtons.LB),
        nameof(SCButtons.RB),
        nameof(SCButtons.LT),
        nameof(SCButtons.RT),
        nameof(SCButtons.STICKPRESS),
        nameof(SCButtons.RPAD),
        nameof(SCButtons.LPAD),
        nameof(SCButtons.LGRIP),
        nameof(SCButtons.RGRIP),
    ]

    def __init__(self, app, config=None):
        self.app = app
        self.current = self._ensure_config({})
        filename = self._make_controller_image_path(ControllerImage.DEFAULT)
        SVGWidget.__init__(self, filename)
        if config:
            self._controller_image.use_config(config)

    def _make_controller_image_path(self, img):
        return os.path.join(self.app.imagepath,
                            "controller-images/%s.svg" % (img, ))

    def get_config(self):
        """
		Returns last used config
		"""
        return self.current

    def _ensure_config(self, data):
        """ Ensure that required keys are present in config data """
        data['gui'] = data.get('gui', {})
        data['gui']['background'] = data['gui'].get("background", "sc")
        data['gui']['buttons'] = data['gui'].get(
            "buttons") or self._get_default_images()
        data['buttons'] = data.get(
            "buttons") or ControllerImage.DEFAULT_BUTTONS
        data['axes'] = data.get("axes") or ControllerImage.DEFAULT_AXES
        data['gyros'] = data.get("gyros", data['gui']["background"] == "sc")
        return data

    @staticmethod
    def get_names(dict_or_tuple):
        """
		There are three different ways how button and axis names are stored
		in config. This wrapper provides unified way to get list of them.
		"""
        if type(dict_or_tuple) in (list, tuple):
            return dict_or_tuple
        return [(x["axis"] if type(x) == dict else x)
                for x in dict_or_tuple.values()]

    def use_config(self, config):
        """
		Loads controller settings from provided config, adding default values
		when needed. Returns same config.
		"""
        self.current = self._ensure_config(config or {})
        self.set_image(
            os.path.join(
                self.app.imagepath, "controller-images/%s.svg" %
                (self.current["gui"]["background"], )))
        self._fill_button_images(self.current["gui"]["buttons"])
        self.hilight({})
        return self.current

    def get_button_groups(self):
        groups = json.loads(
            open(
                os.path.join(self.app.imagepath, "button-images",
                             "groups.json"), "r").read())
        return {
            x['key']: x['buttons']
            for x in groups if x['type'] == "buttons"
        }

    def _get_default_images(self):
        return self.get_button_groups()[ControllerImage.DEFAULT]

    def _fill_button_images(self, buttons):
        e = self.edit()
        SVGEditor.update_parents(e)
        target = SVGEditor.get_element(e, "controller")
        target_x, target_y = SVGEditor.get_translation(target)
        for i in xrange(len(ControllerImage.BUTTONS_WITH_IMAGES)):
            b = nameof(ControllerImage.BUTTONS_WITH_IMAGES[i])
            try:
                elm = SVGEditor.get_element(e, "AREA_%s" % (b, ))
                if elm is None:
                    log.warning("Area for button %s not found", b)
                    continue
                x, y = SVGEditor.get_translation(elm)
                scale = 1.0
                if "scc-button-scale" in elm.attrib:
                    w, h = SVGEditor.get_size(elm)
                    scale = float(elm.attrib['scc-button-scale'])
                    tw, th = w * scale, h * scale
                    if scale < 1.0:
                        x += (w - tw) * 0.5
                        y += (h - th) * 0.5
                    else:
                        x -= (tw - w) * 0.25
                        y -= (th - h) * 0.25
                path = os.path.join(self.app.imagepath, "button-images",
                                    "%s.svg" % (buttons[i], ))
                img = SVGEditor.get_element(SVGEditor.load_from_file(path),
                                            "button")
                img.attrib["transform"] = "translate(%s, %s) scale(%s)" % (
                    x - target_x, y - target_y, scale)
                img.attrib["id"] = b
                SVGEditor.add_element(target, img)
            except Exception, err:
                log.warning("Failed to add image for button %s", b)
                log.exception(err)
        e.commit()