示例#1
0
 def parse_menu(self):
     if self.args.from_profile:
         try:
             self._menuid = self.args.items[0]
             self.items = MenuData.from_profile(self.args.from_profile,
                                                self._menuid)
         except IOError:
             print >> sys.stderr, '%s: error: profile file not found' % (
                 sys.argv[0])
             return False
         except ValueError:
             print >> sys.stderr, '%s: error: menu not found' % (
                 sys.argv[0])
             return False
     elif self.args.from_file:
         try:
             self._menuid = self.args.from_file
             self.items = MenuData.from_file(self.args.from_file)
         except:
             print >> sys.stderr, '%s: error: failed to load menu file' % (
                 sys.argv[0])
             return False
     else:
         try:
             self.items = MenuData.from_args(self.args.items)
             self._menuid = None
         except ValueError:
             print >> sys.stderr, '%s: error: invalid number of arguments' % (
                 sys.argv[0])
             return False
     return True
示例#2
0
	def parse_menu(self):
		if self.args.from_profile:
			try:
				self._menuid = self.args.items[0]
				self.items = MenuData.from_profile(self.args.from_profile, self._menuid)
			except IOError:
				print >>sys.stderr, '%s: error: profile file not found' % (sys.argv[0])
				return False
			except ValueError:
				print >>sys.stderr, '%s: error: menu not found' % (sys.argv[0])
				return False
		elif self.args.from_file:
			try:
				self._menuid = self.args.from_file
				self.items = MenuData.from_file(self.args.from_file)
			except:
				print >>sys.stderr, '%s: error: failed to load menu file' % (sys.argv[0])
				return False
		else:
			try:
				self.items = MenuData.from_args(self.args.items)
				self._menuid = None
			except ValueError:
				print >>sys.stderr, '%s: error: invalid number of arguments' % (sys.argv[0])
				return False
		return True
示例#3
0
    def parse_argumets(self, argv):
        if not OSDWindow.parse_argumets(self, argv):
            return False
        if not self.config:
            self.config = Config()
        if self.args.from_profile:
            try:
                self._menuid = self.args.items[0]
                self.items = MenuData.from_profile(self.args.from_profile,
                                                   self._menuid)
            except IOError:
                print >> sys.stderr, '%s: error: profile file not found' % (
                    sys.argv[0])
                return False
            except ValueError:
                print >> sys.stderr, '%s: error: menu not found' % (
                    sys.argv[0])
                return False
        elif self.args.from_file:
            #try:
            data = json.loads(open(self.args.from_file, "r").read())
            self._menuid = self.args.from_file
            self.items = MenuData.from_json_data(data)
            #except:
            #	print >>sys.stderr, '%s: error: failed to load menu file' % (sys.argv[0])
            #	return False
        else:
            try:
                self.items = MenuData.from_args(self.args.items)
                self._menuid = None
            except ValueError:
                print >> sys.stderr, '%s: error: invalid number of arguments' % (
                    sys.argv[0])
                return False

        # Parse simpler arguments
        self._control_with = self.args.control_with
        self._confirm_with = self.args.confirm_with
        self._cancel_with = self.args.cancel_with

        if self.args.use_cursor:
            self.enable_cursor()

        # Create buttons that are displayed on screen
        self.items = self.items.generate(self)
        for item in self.items:
            item.widget = self.generate_widget(item)
        self.pack_items(self.parent, self.items)
        if len(self.items) == 0:
            print >> sys.stderr, '%s: error: no items in menu' % (sys.argv[0])
            return False

        if self.args.print_items:
            max_id_len = max(*[len(x.id) for x in self.items])
            row_format = "{:>%s}:\t{}" % (max_id_len, )
            for item in self.items:
                print row_format.format(item.id, item.label)
        return True
示例#4
0
	def parse_argumets(self, argv):
		if not OSDWindow.parse_argumets(self, argv):
			return False
		if not self.config:
			self.config = Config()
		if self.args.from_profile:
			try:
				self._menuid = self.args.items[0]
				self.items = MenuData.from_profile(self.args.from_profile, self._menuid)
			except IOError:
				print >>sys.stderr, '%s: error: profile file not found' % (sys.argv[0])
				return False
			except ValueError:
				print >>sys.stderr, '%s: error: menu not found' % (sys.argv[0])
				return False
		elif self.args.from_file:
			#try:
			data = json.loads(open(self.args.from_file, "r").read())
			self._menuid = self.args.from_file
			self.items = MenuData.from_json_data(data)
			#except:
			#	print >>sys.stderr, '%s: error: failed to load menu file' % (sys.argv[0])
			#	return False
		else:
			try:
				self.items = MenuData.from_args(self.args.items)
				self._menuid = None
			except ValueError:
				print >>sys.stderr, '%s: error: invalid number of arguments' % (sys.argv[0])
				return False
		
		# Parse simpler arguments
		self._control_with = self.args.control_with
		self._confirm_with = self.args.confirm_with
		self._cancel_with = self.args.cancel_with
		
		print "_control_with", self._control_with
		
		if self.args.use_cursor:
			self.enable_cursor()
		
		# Create buttons that are displayed on screen
		self.items = self.items.generate(self)
		for item in self.items:
			item.widget = self.generate_widget(item)
		self.pack_items(self.parent, self.items)
		if len(self.items) == 0:
			print >>sys.stderr, '%s: error: no items in menu' % (sys.argv[0])
			return False
		
		if self.args.print_items:
			max_id_len = max(*[ len(x.id) for x in self.items ])
			row_format ="{:>%s}:\t{}" % (max_id_len,)
			for item in self.items:
				print row_format.format(item.id, item.label)
		return True
示例#5
0
	def parse_argumets(self, argv):
		if not OSDWindow.parse_argumets(self, argv):
			return False
		if self.args.from_profile:
			try:
				self._menuid = self.args.items[0]
				self.items = MenuData.from_profile(self.args.from_profile, self._menuid)
			except IOError:
				print >>sys.stderr, '%s: error: profile file not found' % (sys.argv[0])
				return False
			except ValueError:
				print >>sys.stderr, '%s: error: menu not found' % (sys.argv[0])
				return False
		elif self.args.from_file:
			try:
				data = json.loads(open(self.args.from_file, "r").read())
				self._menuid = self.args.from_file
				self.items = MenuData.from_json_data(data)
			except:
				print >>sys.stderr, '%s: error: failed to loade menu file' % (sys.argv[0])
				return False
		else:
			try:
				self.items = MenuData.from_args(self.args.items)
				self._menuid = None
			except ValueError:
				print >>sys.stderr, '%s: error: invalid number of arguments' % (sys.argv[0])
				return False
		
		# Parse simpler arguments
		self._control_with = self.args.control_with
		self._confirm_with = self.args.confirm_with
		self._cancel_with = self.args.cancel_with
		
		if self.args.use_cursor:
			self.f.add(self.cursor)
			self.f.show_all()
			self._use_cursor = True
		
		# Create buttons that are displayed on screen
		for item in self.items:
			item.widget = Gtk.Button.new_with_label(item.label)
			item.widget.set_name("osd-menu-item")
			item.widget.set_relief(Gtk.ReliefStyle.NONE)
		self.pack_items(self.parent, self.items)
		if len(self.items) == 0:
			print >>sys.stderr, '%s: error: no items in menu' % (sys.argv[0])
			return False
		return True
    def parse_argumets(self, argv):
        if not OSDWindow.parse_argumets(self, argv):
            return False
        if not self.config:
            self.config = Config()

        try:
            self.items = MenuData.from_args(self.args.items)
            self._menuid = None
        except ValueError:
            print >> sys.stderr, '%s: error: invalid number of arguments' % (
                sys.argv[0])
            return False

        self._text.set_label(self.args.text)

        if self.args.feedback_amplitude:
            side = "LEFT"
            self.feedback = side, int(self.args.feedback_amplitude)

        # Create buttons that are displayed on screen
        items = self.items.generate(self)
        self.items = []
        for item in items:
            item.widget = self.generate_widget(item)
            if item.widget is not None:
                self.items.append(item)
        self.pack_items(self.parent, self.items)
        if len(self.items) == 0:
            print >> sys.stderr, '%s: error: no items in menu' % (sys.argv[0])
            return False

        return True
    def _add_refereced_menu(self, model, menu_id, used):
        """
		As _add_refereced_profile, but reads and parses menu file.
		"""
        if "." in menu_id and menu_id not in used:
            # Dot in id means filename
            used.add(menu_id)
            filename = find_menu(menu_id)
            name = ".".join(menu_id.split(".")[0:-1])
            if name.startswith(".") and menu_is_default(menu_id):
                # Default and hidden, don't bother user with it
                return
            if filename:
                model.append((not menu_is_default(menu_id), _("Menu"), name,
                              filename, True, self.TP_MENU))
                try:
                    menu = MenuData.from_file(filename, ActionParser())
                except Exception, e:
                    # Menu that cannot be parsed shouldn't be exported
                    log.error(e)
                    return
                for item in menu:
                    if isinstance(item, Submenu):
                        self._add_refereced_menu(
                            model,
                            os.path.split(item.filename)[-1], used)
                    if hasattr(item, "action"):
                        self._parse_action(model, item.action, used)
            else:
                model.append((False, _("Menu"), _("%s (not found)") % (name, ),
                              "", False, self.TP_MENU))
示例#8
0
	def parse_argumets(self, argv):
		if not OSDWindow.parse_argumets(self, argv):
			return False
		if not self.config:
			self.config = Config()
		
		try:
			self.items = MenuData.from_args(self.args.items)
			self._menuid = None
		except ValueError:
			print >>sys.stderr, '%s: error: invalid number of arguments' % (sys.argv[0])
			return False
		
		self._text.set_label(self.args.text)
		
		if self.args.feedback_amplitude:
			side = "LEFT"
			self.feedback = side, int(self.args.feedback_amplitude)
		
		# Create buttons that are displayed on screen
		items = self.items.generate(self)
		self.items = []
		for item in items:
			item.widget = self.generate_widget(item)
			if item.widget is not None:
				self.items.append(item)
		self.pack_items(self.parent, self.items)
		if len(self.items) == 0:
			print >>sys.stderr, '%s: error: no items in menu' % (sys.argv[0])
			return False
		
		return True
示例#9
0
	def _add_refereced_menu(self, model, menu_id, used):
		"""
		As _add_refereced_profile, but reads and parses menu file.
		"""
		if "." in menu_id and menu_id not in used:
			# Dot in id means filename
			used.add(menu_id)
			filename = find_menu(menu_id)
			name = ".".join(menu_id.split(".")[0:-1])
			if name.startswith(".") and menu_is_default(menu_id):
				# Default and hidden, don't bother user with it
				return
			if filename:
				model.append((not menu_is_default(menu_id), _("Menu"), name,
						filename, True, self.TP_MENU))
				try:
					menu = MenuData.from_file(filename, ActionParser())
				except Exception, e:
					# Menu that cannot be parsed shouldn't be exported
					log.error(e)
					return
				for item in menu:
					if isinstance(item, Submenu):
						self._add_refereced_menu(model, os.path.split(item.filename)[-1], used)
					if hasattr(item, "action"):
						self._parse_action(model, item.action, used)
			else:
				model.append((False, _("Menu"), _("%s (not found)") % (name,),
						"", False, self.TP_MENU))
示例#10
0
 def _load_items_from_file(self, id):
     for p in (get_menus_path(), get_default_menus_path()):
         path = os.path.join(p, "%s.menu" % (id, ))
         if os.path.exists(path):
             return MenuData.from_file(path, TalkingActionParser())
     # Menu file not found
     return None
示例#11
0
		def export_menu(tar, filename):
			try:
				menu = MenuData.from_json_data(json.loads(open(filename, "r").read()), ActionParser())
				tar.add(filename, arcname=os.path.split(filename)[-1], recursive=False)
			except Exception, e:
				# Menu that cannot be parsed shouldn't be exported
				log.error(e)
				return False
示例#12
0
	def _load_items_from_file(self, id):
		for p in (get_menus_path(), get_default_menus_path()):
			path = os.path.join(p, "%s.menu" % (id,))
			if os.path.exists(path):
				data = json.loads(open(path, "r").read())
				return MenuData.from_json_data(data, TalkingActionParser())
		# Menu file not found
		return None
示例#13
0
 def _load_items_from_file(self, id):
     for p in (get_menus_path(), get_default_menus_path()):
         path = os.path.join(p, "%s.menu" % (id, ))
         if os.path.exists(path):
             data = json.loads(open(path, "r").read())
             return MenuData.from_json_data(data, TalkingActionParser())
     # Menu file not found
     return None
示例#14
0
	def load(self, filename):
		""" Loads profile from file. Returns self """
		data = json.loads(open(filename, "r").read())
		# Version
		try:
			version = int(data["version"])
		except:
			version = 0
		
		# Buttons
		self.buttons = {}
		for x in SCButtons:
			self.buttons[x] = self.parser.from_json_data(data["buttons"], x.name)
		
		# Stick & gyro
		self.stick = self.parser.from_json_data(data, "stick")
		self.gyro = self.parser.from_json_data(data, "gyro")
		
		if "triggers" in data:
			# Old format
			# Triggers
			self.triggers = ({
				x : self.parser.from_json_data(data["triggers"], x) for x in Profile.TRIGGERS
			})
			
			# Pads
			self.pads = {
				Profile.LEFT	: self.parser.from_json_data(data, "left_pad"),
				Profile.RIGHT	: self.parser.from_json_data(data, "right_pad"),
			}
		else:
			# New format
			# Triggers
			self.triggers = {
				Profile.LEFT	: self.parser.from_json_data(data, "trigger_left"),
				Profile.RIGHT	: self.parser.from_json_data(data, "trigger_right"),
			}
		
			# Pads
			self.pads = {
				Profile.LEFT	: self.parser.from_json_data(data, "pad_left"),
				Profile.RIGHT	: self.parser.from_json_data(data, "pad_right"),
			}
		
		# Menus
		self.menus = {}
		if "menus" in data:
			for id in data["menus"]:
				for invalid_char in ".:/":
					if invalid_char in id:
						raise ValueError("Invalid character '%s' in menu id '%s'" % (invalid_char, id))
				self.menus[id] = MenuData.from_json_data(data["menus"][id], self.parser)
		
		# Conversion
		if version < Profile.VERSION:
			self._convert(version)
		
		return self
示例#15
0
    def load_cbMIs(self):
        """
		See above. This method just parses Default menu and checks
		boxes for present menu items.
		"""
        try:
            data = MenuData.from_fileobj(open(find_menu("Default.menu"), "r"))
        except Exception, e:
            # Shouldn't really happen
            log.error(traceback.format_exc())
            return
 def export_menu(tar, filename):
     try:
         menu = MenuData.from_json_data(
             json.loads(open(filename, "r").read()), ActionParser())
         tar.add(filename,
                 arcname=os.path.split(filename)[-1],
                 recursive=False)
     except Exception, e:
         # Menu that cannot be parsed shouldn't be exported
         log.error(e)
         return False
示例#17
0
    def _generate_menudata(self):
        """
		Generates MenuData instance from items in list
		"""
        model = self.builder.get_object("tvItems").get_model()
        data = MenuData(*[i[0].item for i in model])
        i = 1
        for item in data:
            item.id = "item%s" % (i, )
            i += 1
        return data
示例#18
0
    def on_cbMI_toggled(self, widget):
        """
		Called when one of 'Default Menu Items' checkboxes is toggled.
		This actually does kind of magic:
		- 1st, default menu file is loaded
		- 2nd, based on widget name, option from DEFAULT_MENU_OPTIONS is
		  selected
		- 3rd, if this option is not present in loaded menu and checkbox is
		  toggled on, option is added
		- (same for option that is present while checkbox was toggled off)
		- 4rd, default menu is saved
		"""
        if self._recursing: return
        try:
            data = MenuData.from_fileobj(open(find_menu("Default.menu"), "r"),
                                         GuiActionParser())
            index = int(widget.get_name().split("_")[-1])
            instance = GlobalSettings._make_mi_instance(index)
        except Exception, e:
            log.error(traceback.format_exc())
            self._recursing = True
            widget.set_active(not widget.get_active())
            self._recursing = False
            return
示例#19
0
	def import_scc_tar(self, filename):
		"""
		Imports packaged profiles.
		Checks for shell() actions everywhere and ask user to
		enter main name, check generated ones and optionaly change
		them as he wish.
		"""
		files = self.builder.get_object("lstImportPackage")
		try:
			# Open tar
			tar = tarfile.open(filename, "r:gz")
			files.clear()
			# Grab 1st profile
			name = tar.extractfile(Export.PN_NAME).read()
			main_profile = "%s.sccprofile" % name
			parser = GuiActionParser()
			o = GObject.GObject()
			o.obj = Profile(parser).load_fileobj(tar.extractfile(main_profile))
			files.append(( 2, name, name, _("(profile)"), o ))
			for x in tar:
				name = ".".join(x.name.split(".")[0:-1])
				if x.name.endswith(".sccprofile") and x.name != main_profile:
					o = GObject.GObject()
					o.obj = Profile(parser).load_fileobj(tar.extractfile(x))
					files.append(( True, name, name, _("(profile)"), o ))
				elif x.name.endswith(".menu"):
					o = GObject.GObject()
					o.obj = MenuData.from_fileobj(tar.extractfile(x), parser)
					files.append(( True, name, name, _("(menu)"), o ))
		except Exception, e:
			# Either entire tar or some profile cannot be parsed.
			# Display error message and let user to quit
			# Error message reuses same page as above.
			log.error(e)
			self.error(str(e))
			return
    def import_scc_tar(self, filename):
        """
		Imports packaged profiles.
		Checks for shell() actions everywhere and ask user to
		enter main name, check generated ones and optionaly change
		them as he wish.
		"""
        files = self.builder.get_object("lstImportPackage")
        try:
            # Open tar
            tar = tarfile.open(filename, "r:gz")
            files.clear()
            # Grab 1st profile
            name = tar.extractfile(Export.PN_NAME).read()
            main_profile = "%s.sccprofile" % name
            parser = GuiActionParser()
            o = GObject.GObject()
            o.obj = Profile(parser).load_fileobj(tar.extractfile(main_profile))
            files.append((2, name, name, _("(profile)"), o))
            for x in tar:
                name = ".".join(x.name.split(".")[0:-1])
                if x.name.endswith(".sccprofile") and x.name != main_profile:
                    o = GObject.GObject()
                    o.obj = Profile(parser).load_fileobj(tar.extractfile(x))
                    files.append((True, name, name, _("(profile)"), o))
                elif x.name.endswith(".menu"):
                    o = GObject.GObject()
                    o.obj = MenuData.from_fileobj(tar.extractfile(x), parser)
                    files.append((True, name, name, _("(menu)"), o))
        except Exception, e:
            # Either entire tar or some profile cannot be parsed.
            # Display error message and let user to quit
            # Error message reuses same page as above.
            log.error(e)
            self.error(str(e))
            return
示例#21
0
                items.insert(pos, Separator(instance.label))
                pos += 1
            items.insert(pos, instance)
        else:
            if isinstance(instance, MenuGenerator):
                items = [
                    x for x in items if not (
                        isinstance(x, Separator) and x.label == instance.label)
                ]
            items = [
                x for x in items
                if instance.describe().strip(" >") != x.describe().strip(" >")
            ]

        path = os.path.join(get_menus_path(), "Default.menu")
        data = MenuData(*items)
        jstr = Encoder(sort_keys=True, indent=4).encode(data)
        open(path, "w").write(jstr)
        log.debug("Wrote menu file %s", path)

    def load_cbMIs(self):
        """
		See above. This method just parses Default menu and checks
		boxes for present menu items.
		"""
        try:
            data = MenuData.from_fileobj(open(find_menu("Default.menu"), "r"))
        except Exception, e:
            # Shouldn't really happen
            log.error(traceback.format_exc())
            return
示例#22
0
    def load(self, filename):
        """ Loads profile from file. Returns self """
        data = json.loads(open(filename, "r").read())
        # Version
        try:
            version = int(data["version"])
        except:
            version = 0

        # Buttons
        self.buttons = {}
        for x in SCButtons:
            self.buttons[x] = self.parser.from_json_data(
                data["buttons"], x.name)

        # Stick & gyro
        self.stick = self.parser.from_json_data(data, "stick")
        self.gyro = self.parser.from_json_data(data, "gyro")

        if "triggers" in data:
            # Old format
            # Triggers
            self.triggers = ({
                x: self.parser.from_json_data(data["triggers"], x)
                for x in Profile.TRIGGERS
            })

            # Pads
            self.pads = {
                Profile.LEFT: self.parser.from_json_data(data, "left_pad"),
                Profile.RIGHT: self.parser.from_json_data(data, "right_pad"),
            }
        else:
            # New format
            # Triggers
            self.triggers = {
                Profile.LEFT: self.parser.from_json_data(data, "trigger_left"),
                Profile.RIGHT:
                self.parser.from_json_data(data, "trigger_right"),
            }

            # Pads
            self.pads = {
                Profile.LEFT: self.parser.from_json_data(data, "pad_left"),
                Profile.RIGHT: self.parser.from_json_data(data, "pad_right"),
            }

        # Menus
        self.menus = {}
        if "menus" in data:
            for id in data["menus"]:
                for invalid_char in ".:/":
                    if invalid_char in id:
                        raise ValueError(
                            "Invalid character '%s' in menu id '%s'" %
                            (invalid_char, id))
                self.menus[id] = MenuData.from_json_data(
                    data["menus"][id], self.parser)

        # Conversion
        if version < Profile.VERSION:
            self._convert(version)

        return self
示例#23
0
	def load_fileobj(self, fileobj):
		"""
		Loads profile from file-like object.
		Filename attribute is not set, what may cause some trouble if used in GUI.
		
		Returns self.
		"""
		data = json.loads(fileobj.read())
		# Version
		try:
			version = float(data["version"])
		except:
			version = 0
		
		# Settings - Description
		# (stored in key "_", so it's serialized on top of JSON file)
		if "_" not in data:
			self.description = ""
		elif type(data["_"]) == list:
			self.description = "\n".join(data["_"])
		else:
			self.description = data["_"]
		# Settings - Template
		self.is_template = bool(data["is_template"]) if "is_template" in data else False
		
		# Buttons
		self.buttons = {}
		for x in SCButtons:
			self.buttons[x] = self.parser.from_json_data(data["buttons"], x.name)
		# Pressing stick is interpreted as STICKPRESS button,
		# formely called just STICK
		if "STICK" in data["buttons"] and "STICKPRESS" not in data["buttons"]:
			self.buttons[SCButtons.STICKPRESS] = self.parser.from_json_data(
					data["buttons"], "STICK")
		
		# Stick & gyro
		self.stick = self.parser.from_json_data(data, "stick")
		self.gyro = self.parser.from_json_data(data, "gyro")
		
		if "triggers" in data:
			# Old format
			# Triggers
			self.triggers = ({
				x : self.parser.from_json_data(data["triggers"], x) for x in Profile.TRIGGERS
			})
			
			# Pads
			self.pads = {
				Profile.LEFT	: self.parser.from_json_data(data, "left_pad"),
				Profile.RIGHT	: self.parser.from_json_data(data, "right_pad"),
				Profile.CPAD	: NoAction()
			}
		else:
			# New format
			# Triggers
			self.triggers = {
				Profile.LEFT	: self.parser.from_json_data(data, "trigger_left"),
				Profile.RIGHT	: self.parser.from_json_data(data, "trigger_right"),
			}
			
			# Pads
			self.pads = {
				Profile.LEFT	: self.parser.from_json_data(data, "pad_left"),
				Profile.RIGHT	: self.parser.from_json_data(data, "pad_right"),
				Profile.CPAD	: self.parser.from_json_data(data, "cpad"),
			}
		
		# Menus
		self.menus = {}
		if "menus" in data:
			for id in data["menus"]:
				for invalid_char in ".:/":
					if invalid_char in id:
						raise ValueError("Invalid character '%s' in menu id '%s'" % (invalid_char, id))
				self.menus[id] = MenuData.from_json_data(data["menus"][id], self.parser)
		
		# Conversion
		self.original_version = version		# TODO: This is temporary
		if version < Profile.VERSION:
			self._convert(version)
		
		return self
示例#24
0
    def parse_group(self, group, side):
        """
		Parses output (group) from vdf profile.
		Returns Action.
		"""
        if not "mode" in group:
            raise ParseError("Group without mode")
        mode = group["mode"]
        inputs = VDFProfile.get_inputs(group)

        settings = group["settings"] if "settings" in group else {}
        for o in ("output_trigger", "output_joystick"):
            if o in settings:
                if int(settings[o]) <= 1:
                    side = Profile.LEFT
                else:
                    side = Profile.RIGHT

        if mode == "dpad":
            keys = []
            for k in ("dpad_north", "dpad_south", "dpad_east", "dpad_west"):
                if k in inputs:
                    keys.append(self.parse_button(inputs[k]))
                else:
                    keys.append(NoAction())
            action = DPadAction(*keys)
        elif mode == "four_buttons":
            keys = []
            for k in ("button_y", "button_a", "button_x", "button_b"):
                if k in inputs:
                    keys.append(self.parse_button(inputs[k]))
                else:
                    keys.append(NoAction())
            action = DPadAction(*keys)
        elif mode == "joystick_move":
            if side == Profile.LEFT:
                # Left
                action = XYAction(AxisAction(Axes.ABS_X),
                                  AxisAction(Axes.ABS_Y))
            else:
                # Right
                action = XYAction(AxisAction(Axes.ABS_RX),
                                  AxisAction(Axes.ABS_RY))
        elif mode == "joystick_camera":
            output_joystick = 0
            if 'output_joystick' in settings:
                output_joystick = int(settings['output_joystick'])
            if output_joystick == 0:
                action = BallModifier(
                    XYAction(AxisAction(Axes.ABS_X), AxisAction(Axes.ABS_Y)))
            elif output_joystick == 1:
                action = BallModifier(
                    XYAction(AxisAction(Axes.ABS_RX), AxisAction(Axes.ABS_RY)))
            else:
                # TODO: Absolute mouse? Doesn't seems to do anything in Steam
                action = BallModifier(
                    SensitivityModifier(0.1, 0.1, MouseAction()))
        elif mode == "mouse_joystick":
            action = BallModifier(
                XYAction(AxisAction(Axes.ABS_RX), AxisAction(Axes.ABS_RY)))
        elif mode == "scrollwheel":
            action = BallModifier(
                XYAction(MouseAction(Rels.REL_HWHEEL),
                         MouseAction(Rels.REL_WHEEL)))
        elif mode == "touch_menu":
            # Touch menu is converted to GridMenu
            items = []
            next_item_id = 1
            for k in inputs:
                action = self.parse_button(inputs[k])
                items.append(
                    MenuItem("item_%s" % (next_item_id, ),
                             action.describe(Action.AC_BUTTON), action))
                next_item_id += 1
            # Menu is stored in profile, with generated ID
            menu_id = "menu_%s" % (self.next_menu_id, )
            self.next_menu_id += 1
            self.menus[menu_id] = MenuData(*items)

            action = GridMenuAction(
                menu_id, 'LEFT' if side == Profile.LEFT else 'RIGHT',
                SCButtons.LPAD if side == Profile.LEFT else SCButtons.RPAD)
        elif mode == "absolute_mouse":
            if "click" in inputs:
                if side == Profile.LEFT:
                    self.add_by_binding(SCButtons.LPAD,
                                        self.parse_button(inputs["click"]))
                else:
                    self.add_by_binding(SCButtons.RPAD,
                                        self.parse_button(inputs["click"]))
            if "gyro_axis" in settings:
                if int(settings["gyro_axis"]) == 1:
                    action = MouseAction(ROLL)
                else:
                    action = MouseAction(YAW)
            else:
                action = MouseAction()
        elif mode == "mouse_wheel":
            action = BallModifier(
                XYAction(MouseAction(Rels.REL_HWHEEL),
                         ouseAction(Rels.REL_WHEEL)))
        elif mode == "trigger":
            actions = []
            if "click" in inputs:
                actions.append(
                    TriggerAction(TRIGGER_CLICK,
                                  self.parse_button(inputs["click"])))

            if side == Profile.LEFT:
                actions.append(AxisAction(Axes.ABS_Z))
            else:
                actions.append(AxisAction(Axes.ABS_RZ))

            action = MultiAction.make(*actions)
        elif mode == "mouse_region":
            # Read value and assume dafaults
            scale = float(settings["scale"]) if "scale" in settings else 100.0
            x = float(
                settings["position_x"]) if "position_x" in settings else 50.0
            y = float(
                settings["position_y"]) if "position_y" in settings else 50.0
            w = float(settings["sensitivity_horiz_scale"]
                      ) if "sensitivity_horiz_scale" in settings else 100.0
            h = float(settings["sensitivity_vert_scale"]
                      ) if "sensitivity_vert_scale" in settings else 100.0
            # Apply scale
            w = w * scale / 100.0
            h = h * scale / 100.0
            # Convert to (0, 1) range
            x, y = x / 100.0, 1.0 - (y / 100.0)
            w, h = w / 100.0, h / 100.0
            # Convert to rectangle
            x1 = max(0.0, x - (w * VDFProfile.REGION_IMPORT_FACTOR))
            x2 = min(1.0, x + (w * VDFProfile.REGION_IMPORT_FACTOR))
            y1 = max(0.0, y - (h * VDFProfile.REGION_IMPORT_FACTOR))
            y2 = min(1.0, y + (h * VDFProfile.REGION_IMPORT_FACTOR))

            action = RelAreaAction(x1, y1, x2, y2)
        else:
            raise ParseError("Unknown mode: '%s'" % (group["mode"], ))

        action = VDFProfile.parse_modifiers(group, action, side)
        return action
示例#25
0
    def load_fileobj(self, fileobj):
        """
		Loads profile from file-like object.
		Filename attribute is not set, what may cause some trouble if used in GUI.
		
		Returns self.
		"""
        data = json.loads(fileobj.read())
        # Version
        try:
            version = int(data["version"])
        except:
            version = 0

        # Settings - Description
        # (stored in key "_", so it's serialized on top of JSON file)
        if "_" not in data:
            self.description = ""
        elif type(data["_"]) == list:
            self.description = "\n".join(data["_"])
        else:
            self.description = data["_"]
        # Settings - Template
        self.is_template = bool(
            data["is_template"]) if "is_template" in data else False

        # Buttons
        self.buttons = {}
        for x in SCButtons:
            self.buttons[x] = self.parser.from_json_data(
                data["buttons"], x.name)
        # Pressing stick is interpreted as STICKPRESS button,
        # formely called just STICK
        if "STICK" in data["buttons"] and "STICKPRESS" not in data["buttons"]:
            self.buttons[SCButtons.STICKPRESS] = self.parser.from_json_data(
                data["buttons"], "STICK")

        # Stick & gyro
        self.stick = self.parser.from_json_data(data, "stick")
        self.gyro = self.parser.from_json_data(data, "gyro")

        if "triggers" in data:
            # Old format
            # Triggers
            self.triggers = ({
                x: self.parser.from_json_data(data["triggers"], x)
                for x in Profile.TRIGGERS
            })

            # Pads
            self.pads = {
                Profile.LEFT: self.parser.from_json_data(data, "left_pad"),
                Profile.RIGHT: self.parser.from_json_data(data, "right_pad"),
            }
        else:
            # New format
            # Triggers
            self.triggers = {
                Profile.LEFT: self.parser.from_json_data(data, "trigger_left"),
                Profile.RIGHT:
                self.parser.from_json_data(data, "trigger_right"),
            }

            # Pads
            self.pads = {
                Profile.LEFT: self.parser.from_json_data(data, "pad_left"),
                Profile.RIGHT: self.parser.from_json_data(data, "pad_right"),
            }

        # Menus
        self.menus = {}
        if "menus" in data:
            for id in data["menus"]:
                for invalid_char in ".:/":
                    if invalid_char in id:
                        raise ValueError(
                            "Invalid character '%s' in menu id '%s'" %
                            (invalid_char, id))
                self.menus[id] = MenuData.from_json_data(
                    data["menus"][id], self.parser)

        # Conversion
        if version < Profile.VERSION:
            self._convert(version)

        return self