예제 #1
0
	def choose_editor(self, action, title, id=None):
		""" Chooses apropripate Editor instance for edited action """
		if isinstance(action, SensitivityModifier):
			action = action.action
		if isinstance(action, FeedbackModifier):
			action = action.action
		if id in GYROS:
			e = ActionEditor(self.app, self.on_action_chosen)
			e.set_title(title)
		elif isinstance(action, (ModeModifier, DoubleclickModifier, HoldModifier)) and not is_gyro_enable(action):
			e = ModeshiftEditor(self.app, self.on_action_chosen)
			e.set_title(_("Mode Shift for %s") % (title,))
		elif RingEditor.is_ring_action(action):
			e = RingEditor(self.app, self.on_action_chosen)
			e.set_title(title)
		elif isinstance(action, Type):
			# Type is subclass of Macro
			e = ActionEditor(self.app, self.on_action_chosen)
			e.set_title(title)
		elif isinstance(action, Macro) and not (is_button_togle(action) or is_button_repeat(action)):
			e = MacroEditor(self.app, self.on_action_chosen)
			e.set_title(_("Macro for %s") % (title,))
		else:
			e = ActionEditor(self.app, self.on_action_chosen)
			e.set_title(title)
		return e
예제 #2
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))
예제 #3
0
	def describe(self, context):
		if self.name: return self.name
		axis, neg, pos = self._get_axis_description()
		if context in (Action.AC_STICK, Action.AC_PAD):
			xy = "X" if self.parameters[0] in AxisAction.X else "Y"
			return _("%s %s (reversed)") % (axis, xy)
		return _("Reverse %s Axis") % (axis,)
예제 #4
0
	def describe(self, context):
		if self.name: return self.name
		if self.parameters[0] == Rels.REL_WHEEL:
			return _("Circular Wheel")
		elif self.parameters[0] == Rels.REL_HWHEEL:
			return _("Circular Horizontal Wheel")
		return _("Circular Mouse %s") % (self.parameters[0].name.split("_", 1)[-1],)
예제 #5
0
파일: gyro.py 프로젝트: kozec/sc-controller
	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
예제 #6
0
	def on_menus_loaded(self, menus):
		cb = self.builder.get_object("cbMenus")
		cb.set_row_separator_func( lambda model, iter : model.get_value(iter, 1) is None )
		model = cb.get_model()
		model.clear()
		i, current_index = 0, 0
		if self.allow_in_profile:
			# Add menus from profile
			for key in sorted(self.app.current.menus):
				model.append((key, key))
				if self._current_menu == key:
					current_index = i
				i += 1
			if i > 0:
				model.append((None, None))	# Separator
				i += 1
		if self.allow_globals:
			for f in menus:
				key = f.get_basename()
				name = key
				if "." in name:
					name = _("%s (global)" % (name.split(".")[0]))
				model.append((name, key))
				if self._current_menu == key:
					current_index = i
				i += 1
		if i > 0:
			model.append((None, None))	# Separator
		model.append(( _("New Menu..."), "" ))
		
		self._recursing = True
		cb.set_active(current_index)
		self._recursing = False
		self.on_cbMenus_changed()
예제 #7
0
	def on_txName2_changed(self, *a):
		txName2 =			self.builder.get_object("txName2")
		btNext =			self.enable_next(True, self.on_scc_import_confirmed)
		files =				self.builder.get_object("lstImportPackage")
		cbImportHidden =	self.builder.get_object("cbImportPackageHidden")
		cbImportVisible =	self.builder.get_object("cbImportPackageVisible")
		cbImportNone =		self.builder.get_object("cbImportPackageNone")
		rvAdvanced =		self.builder.get_object("rvImportPackageAdvanced")
		btNext.set_label('Apply')
		btNext.set_use_stock(True)
		main_name = txName2.get_text().decode("utf-8")
		if self.check_name(main_name):
			btNext.set_sensitive(True)
		else:
			btNext.set_sensitive(False)
		
		cbImportHidden.set_label(_("Import as hidden menus and profiles named \".%s:name\"") % (main_name,))
		cbImportVisible.set_label(_("Import normaly, with names formated as \"%s:name\"") % (main_name,))
		
		for i in xrange(0, len(files)):
			enabled, name, importas, type, obj = files[i]
			if enabled == 2:
				importas = main_name
			elif cbImportHidden.get_active():
				importas = ".%s:%s" % (main_name, name)
				enabled = 1
			elif cbImportVisible.get_active():
				importas = "%s:%s" % (main_name, name)
				enabled = 1
			elif cbImportNone.get_active():
				enabled = 0
			files[i] = enabled, name, importas, type, obj
예제 #8
0
	def on_button(self, keycode, pressed):
		#if len(self.grabbed) == 2 and self.grabbed[X] != None:
		#	# Already grabbed one axis, don't grab buttons
		#	return
		if keycode in self.grabbed:
			# Don't allow same button to be used twice
			return
		if not pressed:
			if len(self.grabbed) < 4:
				self.grabbed = [ None ] * 4
			if self.grabbed[0] is None:
				self.grabbed[0] = keycode
				self.set_message(_("Move DPAD to right"))
			elif self.grabbed[1] is None:
				self.grabbed[1] = keycode
				self.set_message(_("Move DPAD up"))
			elif self.grabbed[2] is None:
				self.grabbed[2] = keycode
				self.set_message(_("Move DPAD down"))
			elif self.grabbed[3] is None:
				self.grabbed[3] = keycode
				self.set_message(str(self.grabbed))
				grabbed = [] + self.grabbed
				for w in self.what:
					for negative in (False, True):
						keycode, grabbed = grabbed[0], grabbed[1:]
						w.reset()
						self.set_mapping(keycode, DPadEmuData(w, negative))
				self.parent.generate_unassigned()
				self.parent.generate_raw_data()
				self.cancel()
예제 #9
0
	def set_profile_modified(self, has_changes, is_template=False):
		"""
		Called to signalize that profile has changes to save in UI
		by displaying "changed" next to profile name and showing Save button.
		
		Returns giofile for currently selected profile. If profile is set as
		changed, giofile is automatically changed to 'original/filename.mod',
		so application can save changes without overwriting original wile.
		"""
		if has_changes:
			if not self._savebutton:
				# Save button has to be created
				self._savebutton = ButtonInRevealer(
					"gtk-save", _("Save changes"),
					self.on_savebutton_clicked)
				self._box.pack_start(self._savebutton, False, True, 0)
				self.show_all()
			self._savebutton.set_reveal_child(True)
			iter = self._combo.get_active_iter()
			if is_template:
				self._model.set_value(iter, 2, _("(changed template)"))
			else:
				self._model.set_value(iter, 2, _("(changed)"))
		else:
			if self._savebutton:
				# Nothing to hide if there is no revealer
				self._savebutton.set_reveal_child(False)
			for i in self._model:
				i[2] = None
			if is_template:
				iter = self._combo.get_active_iter()
				self._model.set_value(iter, 2, _("(template)"))
예제 #10
0
	def on_mnuMenuDelete_activate(self, *a):
		id = self.get_selected_menu()
		if MenuEditor.menu_is_global(id):
			text = _("Really delete selected global menu?")
		else:
			text = _("Really delete selected menu?")
		
		d = Gtk.MessageDialog(parent=self.editor.window,
			flags = Gtk.DialogFlags.MODAL,
			type = Gtk.MessageType.WARNING,
			buttons = Gtk.ButtonsType.OK_CANCEL,
			message_format = text,
		)
		
		if MenuEditor.menu_is_global(id):
			d.format_secondary_text(_("This action is not undoable!"))
		
		if d.run() == -5: # OK button, no idea where is this defined...
			if MenuEditor.menu_is_global(id):
				fname = os.path.join(get_menus_path(), id)
				try:
					os.unlink(fname)
				except Exception, e:
					log.error("Failed to remove %s: %s", fname, e)
			else:
				del self.app.current.menus[id]
				self.app.on_profile_modified()
			self.load_menu_list()
예제 #11
0
	def describe_button(button):
		if button in ButtonAction.SPECIAL_NAMES:
			return _(ButtonAction.SPECIAL_NAMES[button])
		elif button in MOUSE_BUTTONS:
			return _("Mouse %s") % (button,)
		elif button is None: # or isinstance(button, NoAction):
			return "None"
		return button.name.split("_", 1)[-1]
예제 #12
0
	def on_cbInvertGyro_toggled(self, cb, *a):
		lblGyroEnable = self.builder.get_object("lblGyroEnable")
		if cb.get_active():
			lblGyroEnable.set_label(_("Gyro Disable Button"))
		else:
			lblGyroEnable.set_label(_("Gyro Enable Button"))
		if not self._recursing:
			self.send()
예제 #13
0
	def describe(self, context):
		if self.name: return self.name
		if self._mouse_axis == Rels.REL_WHEEL:
			return _("Wheel")
		elif self._mouse_axis == Rels.REL_HWHEEL:
			return _("Horizontal Wheel")
		elif self._mouse_axis in (PITCH, YAW, ROLL, None):
			return _("Mouse")
		else:
			return _("Mouse %s") % (self._mouse_axis.name.split("_", 1)[-1],)
예제 #14
0
	def describe(self, context):
		if self.name: return self.name
		if self.parameters[0] == Rels.REL_WHEEL:
			return _("Wheel")
		elif self.parameters[0] == Rels.REL_HWHEEL:
			return _("Horizontal Wheel")
		elif self.parameters[0] in (PITCH, YAW, ROLL):
			return _("Mouse")
		else:
			return _("Mouse %s") % (self.parameters[0].name.split("_", 1)[-1],)
예제 #15
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
	def _choose_editor(self, action, cb):
		if isinstance(action, Macro):
			from scc.gui.macro_editor import MacroEditor	# Cannot be imported @ top
			e = MacroEditor(self.app, cb)
			e.set_title(_("Edit Macro"))
		else:
			from scc.gui.action_editor import ActionEditor	# Cannot be imported @ top
			e = ActionEditor(self.app, cb)
			e.set_title(_("Edit Action"))
			e.hide_modeshift()
		return e
예제 #17
0
	def on_sclMenuSize_format_value(self, scale, val):
		cbm = self.builder.get_object("cbMenuType")
		menu_type = cbm.get_model().get_value(cbm.get_active_iter(), 1)
		if menu_type == "radialmenu":
			if val < 1:
				return _("default")
			return  "%s%%" % (int(val),)
		else: # if menu_type == "hmenu"
			val = int(val)
			if val < 2:
				return _("default")
			return str(int(val))
예제 #18
0
	def describe(self, context):
		if self.name: return self.name
		if self.button in ButtonAction.SPECIAL_NAMES:
			return _(ButtonAction.SPECIAL_NAMES[self.button])
		elif self.button == Rels.REL_WHEEL:
			if len(self.parameters) < 2 or self.parameters[1] > 0:
				return _("Wheel UP")
			else:
				return _("Wheel DOWN")
		elif self.button in MOUSE_BUTTONS:
			return _("Mouse %s") % (self.button,)
		return self.button.name.split("_", 1)[-1]
예제 #19
0
	def _choose_editor(self, action, cb):
		if isinstance(action, ModeModifier):
			from scc.gui.modeshift_editor import ModeshiftEditor	# Cannot be imported @ top
			e = ModeshiftEditor(self.app, cb)
			e.set_title(_("Edit Action"))
		else:
			from scc.gui.action_editor import ActionEditor	# Cannot be imported @ top
			e = ActionEditor(self.app, cb)
			e.set_title(_("Edit Action"))
			e.hide_macro()
			e.hide_ring()
		return e
예제 #20
0
	def on_change_delay(self, scale, trash, value, data):
		""" Called when delay slider is moved """
		ms = int(value)
		action = data[0]
		label = data[-1][-2]
		action.delay = value / 1000.0
		if ms < 1000:
			label.set_markup(_("<b>Delay: %sms</b>") % (ms,))
		else:
			s = ms / 1000.0
			label.set_markup(_("<b>Delay: %0.2fs</b>") % (s,))
		self.update_action_field()
예제 #21
0
	def _choose_editor(self, action, title):
		if isinstance(action, SensitivityModifier):
			action = action.action
		if isinstance(action, ModeModifier) and not is_gyro_enable(action):
			e = ModeshiftEditor(self, self.on_action_chosen)
			e.set_title(_("Mode Shift for %s") % (title,))
		elif isinstance(action, Macro):
			e = MacroEditor(self, self.on_action_chosen)
			e.set_title(_("Macro for %s") % (title,))
		else:
			e = ActionEditor(self, self.on_action_chosen)
			e.set_title(title)
		return e
예제 #22
0
	def describe(self, context):
		if self.name: return self.name
		elif self.button == Rels.REL_WHEEL:
			if len(self.parameters) < 2 or self.parameters[1] > 0:
				return _("Wheel UP")
			else:
				return _("Wheel DOWN")
		else:
			rv = [ ]
			for x in (self.button, self.button2):
				if x:
					rv.append(ButtonAction.describe_button(x))
			return ", ".join(rv)
예제 #23
0
파일: app.py 프로젝트: mulark/sc-controller
	def on_new_clicked(self, ps, name):
		new_name = _("Copy of %s") % (name,)
		filename = os.path.join(get_profiles_path(), new_name + ".sccprofile")
		i = 0
		while os.path.exists(filename):
			i += 1
			new_name = _("Copy of %s (%s)") % (name, i)
			filename = os.path.join(get_profiles_path(), new_name + ".sccprofile")
		
		dlg = self.builder.get_object("dlgNewProfile")
		txNewProfile = self.builder.get_object("txNewProfile")
		txNewProfile.set_text(new_name)
		dlg.set_transient_for(self.window)
		dlg.show()
예제 #24
0
파일: app.py 프로젝트: mulark/sc-controller
	def check(self):
		""" Performs various (three) checks and reports possible problems """
		# TODO: Maybe not best place to do this
		try:
			kernel_mods = [ line.split(" ")[0] for line in file("/proc/modules", "r").read().split("\n") ]
		except Exception:
			# Maybe running on BSD or Windows...
			kernel_mods = [ ]
		
		if len(kernel_mods) > 0 and "uinput" not in kernel_mods:
			# There is no uinput
			msg = _('uinput kernel module not loaded')
			msg += "\n\n" + _('Please, consult your distribution manual on how to enable uinput')
			self.show_error(msg)
		elif not os.path.exists("/dev/uinput"):
			# /dev/uinput missing
			msg = _('/dev/uinput doesn\'t exists')
			msg += "\n" + _('uinput kernel module is loaded, but /dev/uinput is missing.')
			#msg += "\n\n" + _('Please, consult your distribution manual on what in the world could cause this.')
			msg += "\n\n" + _('Please, consult your distribution manual on how to enable uinput')
			self.show_error(msg)
		elif not check_access("/dev/uinput"):
			# Cannot acces uinput
			msg = _('You don\'t have required access to /dev/uinput.')
			msg += "\n" + _('This will most likely prevent emulation from working.')
			msg += "\n\n" + _('Please, consult your distribution manual on how to enable uinput')
			self.show_error(msg)
예제 #25
0
	def check_shell_commands(self):
		"""
		Check for shell commands in profiles being imported.
		If there are any shell commands found, displays warning page
		and lets user to confirm import of them.
		
		Othewise, goes straight to next page as if user already confirmed them.
		"""
		grShellCommands =	self.builder.get_object("grShellCommands")
		tvShellCommands =	self.builder.get_object("tvShellCommands")
		files =				self.builder.get_object("lstImportPackage")
		model = tvShellCommands.get_model()
		model.clear()
		# Get all shell commands in all profiles
		for trash, trash, trash, trash, obj in files:
			if isinstance(obj.obj, Profile):
				for a in obj.obj.get_all_actions():
					if isinstance(a, ShellCommandAction):
						model.append((False, a.command))
		
		if len(model) > 0:
			# If there is shell command present, jump to warning page
			self.next_page(grShellCommands)
			btNext = self.enable_next(True, self.shell_import_confirmed)
			btNext.set_label(_("Continue"))
			btNext.set_sensitive(False)
		else:
			# Otherwise continue to next one
			self.shell_import_confirmed()	
예제 #26
0
	def on_btDPAD_clicked(self, b):
		""" 'Select DPAD Left Action' handler """
		i = int(b.get_name())
		ae = ActionEditor(self.app, self.on_choosen)
		ae.set_title(_("Select DPAD Action"))
		ae.set_button(i, self.actions[i])
		ae.show(self.app.window)
예제 #27
0
	def generate_widget(self, item):
		""" Generates gtk widget for specified menutitem """
		if isinstance(item, Separator) and item.label:
			widget = Gtk.Button.new_with_label(item.label)
			widget.set_relief(Gtk.ReliefStyle.NONE)
			widget.set_name("osd-menu-separator")
			return widget
		elif isinstance(item, Separator):
			widget = Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL)
			widget.set_name("osd-menu-separator")
			return widget
		else:
			widget = Gtk.Button.new_with_label(item.label)
			widget.set_relief(Gtk.ReliefStyle.NONE)
			if hasattr(widget.get_children()[0], "set_xalign"):
				widget.get_children()[0].set_xalign(0)
			else:
				widget.get_children()[0].set_halign(Gtk.Align.START)
			if isinstance(item, Submenu):
				item.callback = self.show_submenu
				label1 = widget.get_children()[0]
				label2 = Gtk.Label(_(">>"))
				label2.set_property("margin-left", 30)
				box = Gtk.Box(Gtk.Orientation.HORIZONTAL)
				widget.remove(label1)
				box.pack_start(label1, True, True, 1)
				box.pack_start(label2, False, True, 1)
				widget.add(box)
				widget.set_name("osd-menu-item")
			elif item.id is None:
				widget.set_name("osd-menu-dummy")
			else:
				widget.set_name("osd-menu-item")
			return widget
예제 #28
0
	def on_spMenuSize_format_value(self, spinner):
		val = int(spinner.get_adjustment().get_value())
		if val < 1:
			spinner.get_buffer().set_text(_("auto"), -1)
		else:
			spinner.get_buffer().set_text(str(val), -1)
		return True
예제 #29
0
	def on_cbProfile_changed(self, cb, *a):
		""" Called when user chooses profile in selection combo """
		if self.recursing : return
		model = cb.get_model()
		iter = cb.get_active_iter()
		f = model.get_value(iter, 1)
		if f is None:
			if self.current_file is None:
				cb.set_active(0)
			else:
				self.select_profile(self.current_file.get_path())
			
			new_name = os.path.split(self.current_file.get_path())[-1]
			if new_name.endswith(".mod"): new_name = new_name[0:-4]
			if new_name.endswith(".sccprofile"): new_name = new_name[0:-11]
			new_name = _("Copy of") + " " + new_name
			dlg = self.builder.get_object("dlgNewProfile")
			txNewProfile = self.builder.get_object("txNewProfile")
			txNewProfile.set_text(new_name)
			dlg.set_transient_for(self.window)
			dlg.show()
		else:
			self.load_profile(f)
			if not self.daemon_changed_profile:
				self.dm.set_profile(f.get_path())
			self.save_profile_selection(f.get_path())
예제 #30
0
	def on_btSaveAs_clicked(self, *a):
		# Grab stuff
		tvProfiles	= self.builder.get_object("tvProfiles")
		model, iter = tvProfiles.get_selection().get_selected()
		
		# Determine format
		f = Gtk.FileFilter()
		if self._needs_package():
			f.set_name("SC-Controller Profile Archive")
			fmt = "sccprofile.tar.gz"
		else:
			f.set_name("SC-Controller Profile")
			fmt = "sccprofile"
		f.add_pattern("*.%s" % (fmt,))
		
		# Create dialog
		d = Gtk.FileChooserNative.new(_("Export to File..."),
				self.window, Gtk.FileChooserAction.SAVE)
		d.add_filter(f)
		d.set_do_overwrite_confirmation(True)
		# Set default filename
		d.set_current_name("%s.%s" % (model[iter][2], fmt))
		if d.run() == Gtk.ResponseType.ACCEPT:
			fn = d.get_filename()
			if len(os.path.split(fn)[-1].split(".")) < 2:
				# User wrote filename without extension
				fn = "%s.%s" % (fn, fmt)
			
			if self._needs_package():
				if self._export_package(model[iter][1], fn):
					self.window.destroy()
			else:
				if self._export(model[iter][1], fn):
					self.window.destroy()
예제 #31
0
	def generate(self, menuhandler):
		return _("[ Window Lists ]")
예제 #32
0
	def get_button_title(self):
		return _("DPAD or Menu")
예제 #33
0
 def _bad_id_chars(self, *a):
     self.builder.get_object("lblNope").set_label(
         _('Invalid Menu ID: Please, don\'t use dots (.) or slashes (/).'))
     self.builder.get_object("rvInvalidID").set_reveal_child(True)
     self.builder.get_object("btSave").set_sensitive(False)
예제 #34
0
	def describe(self):
		return _("[ All Profiles ]")
예제 #35
0
class ModeshiftEditor(Editor):
	GLADE = "modeshift_editor.glade"
	BUTTONS = (	# in order as displayed in combobox
		(SCButtons.A,			_('A') ),
		(SCButtons.B,			_('B') ),
		(SCButtons.X,			_('X') ),
		(SCButtons.Y,			_('Y') ),
		(None, None),
		(SCButtons.BACK,		_('Back (select)') ),
		(SCButtons.C,			_('Center') ),
		(SCButtons.START,		_('Start') ),
		(None, None),
		(SCButtons.LGRIP,		_('Left Grip') ),
		(SCButtons.RGRIP,		_('Right Grip') ),
		(SCButtons.LB,			_('Left Bumper') ),
		(SCButtons.RB,			_('Right Bumper') ),
		(None, None),
		(SCButtons.LT,			_('Left Trigger (full)') ),
		(SCButtons.RT,			_('Right Trigger (full)') ),
		("Soft LT",				_('Left Trigger (soft)') ),
		("Soft RT",				_('Right Trigger (soft)') ),
		(None, None),
		(SCButtons.STICKPRESS,	_('Stick Pressed') ),
		(SCButtons.LPAD,		_('Left Pad Pressed') ),
		(SCButtons.RPAD,		_('Right Pad Pressed') ),
		(SCButtons.LPADTOUCH,	_('Left Pad Touched') ),
		(SCButtons.RPADTOUCH,	_('Right Pad Touched') ),
	)
	
	def __init__(self, app, callback):
		Editor.__init__(self)
		self.app = app
		self.id = None
		self.mode = Action.AC_BUTTON
		self.ac_callback = callback
		self.soft_level = -1
		self.current_page = 0
		self.actions = ( [], [], [] )
		self.nomods = [ NoAction(), NoAction(), NoAction() ]
		self.setup_widgets()
	
	
	def setup_widgets(self):
		Editor.setup_widgets(self)
		
		cbButtonChooser = self.builder.get_object("cbButtonChooser")
		cbButtonChooser.set_row_separator_func( lambda model, iter : model.get_value(iter, 0) is None )
		
		b = lambda a : self.builder.get_object(a)
		self.action_widgets = (
			# Order goes: Grid, 1st Action Button, Clear Button
			# 1st group, 'pressed'
			( b('grActions'),		b('btDefault'),		b('btClearDefault') ),
			# 2nd group, 'hold'
			( b('grHold'),			b('btHold'),		b('btClearHold') ),
			# 2nd group, 'double-click'
			( b('grDoubleClick'),	b('btDoubleClick'),	b('btClearDoubleClick') ),
		)
		
		headerbar(self.builder.get_object("header"))
	
	
	def on_Dialog_destroy(self, *a):
		self.remove_added_widget()
	
	
	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)
	
	
	def _add_action(self, index, what, action):
		cbButtonChooser = self.builder.get_object("cbButtonChooser")
		adjSoftLevel = self.builder.get_object("adjSoftLevel")
		rvSoftLevel = self.builder.get_object("rvSoftLevel")
		grActions = self.action_widgets[index][0]
		model = cbButtonChooser.get_model()
		
		for row in model:
			item = model.get_value(row.iter, 0)
			if item:
				if item == nameof(what):
					model.remove(row.iter)
					break
				if isinstance(what, RangeOP) and item.startswith("Soft"):
					if nameof(what.what) == item.split(" ")[-1]:
						model.remove(row.iter)
						break
		try:
			while model.get_value(model[0].iter, 0) is None:
				model.remove(model[0].iter)
			cbButtonChooser.set_active(0)
		except: pass
		
		i = len(self.actions[index]) + 1
		l = Gtk.Label()
		if isinstance(what, RangeOP) and what.op == ">=":
			if self.soft_level == -1:
				# First Range added, load level from it
				self.soft_level = what.value if what.value > 0.0 else 0.75
				adjSoftLevel.set_value(self.soft_level)
				rvSoftLevel.set_reveal_child(True)
				what.value = -1
			if what.value == -1:
				# Range with value taken from "Soft Pull Level" slider
				l.set_markup("<b>%s (soft pull)</b>" % (nameof(what.what),))
			else:
				# Any other range
				l.set_markup("<b>%s</b>" % (nameof(what),))
		else:
			l.set_markup("<b>%s</b>" % (nameof(what),))
		l.set_xalign(0.0)
		b = Gtk.Button.new_with_label(action.describe(self.mode))
		b.set_property("hexpand", True)
		b.connect('clicked', self.on_actionb_clicked, index, what)
		clearb = Gtk.Button()
		clearb.set_image(Gtk.Image.new_from_stock("gtk-delete", Gtk.IconSize.SMALL_TOOLBAR))
		clearb.set_relief(Gtk.ReliefStyle.NONE)
		clearb.connect('clicked', self.on_clearb_clicked, index, what)
		grActions.attach(l,			0, i, 1, 1)
		grActions.attach(b,			1, i, 1, 1)
		grActions.attach(clearb,	2, i, 1, 1)
		
		self.actions[index].append([ what, action, l, b, clearb ])
		grActions.show_all()
	
	
	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)
	
	
	def _choose_editor(self, action, cb):
		if isinstance(action, Macro):
			from scc.gui.macro_editor import MacroEditor	# Cannot be imported @ top
			e = MacroEditor(self.app, cb)
			e.set_title(_("Edit Macro"))
		else:
			from scc.gui.action_editor import ActionEditor	# Cannot be imported @ top
			e = ActionEditor(self.app, cb)
			e.set_title(_("Edit Action"))
			e.hide_modeshift()
		return e
	
	
	def on_actionb_clicked(self, trash, index, clicked_button):
		for i in self.actions[index]:
			button, action, l, b, clearb = i
			if button == clicked_button:
				def on_chosen(id, action):
					b.set_label(action.describe(self.mode))
					i[1] = action
				
				ae = self._choose_editor(action, on_chosen)
				ae.set_input(self.id, action, mode = self.mode)
				ae.show(self.window)
				return
	
	
	def on_ntbMore_switch_page(self, ntb, box, index):
		self.current_page = index
		self._fill_button_chooser()
		self.builder.get_object("cbButtonChooser").set_sensitive(box.get_sensitive())
		self.builder.get_object("btAddAction").set_sensitive(box.get_sensitive())
	
	
	def on_nomodbt_clicked(self, button, *a):
		actionButton = self.action_widgets[self.current_page][1]
		
		def on_chosen(id, action):
			actionButton.set_label(action.describe(self.mode))
			self.nomods[self.current_page] = action
		
		ae = self._choose_editor(self.nomods[self.current_page], on_chosen)
		ae.set_input(self.id, self.nomods[self.current_page], mode = self.mode)
		ae.show(self.window)
	
	
	def on_nomodclear_clicked(self, button, *a):
		self.nomods[self.current_page] = NoAction()
		actionButton = self.action_widgets[self.current_page][1]
		actionButton.set_label(self.nomods[self.current_page].describe(self.mode))
	
	
	def on_btAddAction_clicked(self, *a):
		cbButtonChooser = self.builder.get_object("cbButtonChooser")
		item = cbButtonChooser.get_model().get_value(cbButtonChooser.get_active_iter(), 0)
		if item.startswith("Soft"):
			b = getattr(SCButtons, item.split(" ")[-1])
			rng = RangeOP(b, ">=", -1)
			self._add_action(self.current_page, rng, NoAction())
		else:
			b = getattr(SCButtons, item)
			self._add_action(self.current_page, b, NoAction())
	
	
	def on_sclSoftLevel_format_value(self, scale, value):
		return  "%s%%" % (int(value * 100.0),)
	
	
	def on_btClear_clicked(self, *a):
		""" Handler for clear button """
		action = NoAction()
		if self.ac_callback is not None:
			self.ac_callback(self.id, action)
		self.close()
	
	
	def on_btCustomActionEditor_clicked(self, *a):
		""" Handler for 'Custom Editor' button """
		from scc.gui.action_editor import ActionEditor	# Can't be imported on top
		e = ActionEditor(self.app, self.ac_callback)
		e.set_input(self.id, self._make_action(), mode = self.mode)
		e.hide_action_buttons()
		e.hide_advanced_settings()
		e.set_title(self.window.get_title())
		e.force_page(e.load_component("custom"), True)
		self.send_added_widget(e)
		self.close()
		e.show(self.get_transient_for())
	
	
	def on_cbHoldFeedback_toggled(self, cb, *a):
		rvHoldFeedbackAmplitude = self.builder.get_object("rvHoldFeedbackAmplitude")
		rvHoldFeedbackAmplitude.set_reveal_child(cb.get_active())
	
	
	def on_btOK_clicked(self, *a):
		""" Handler for OK button """
		if self.ac_callback is not None:
			self.ac_callback(self.id, self._make_action())
		self.close()
	
	
	def _make_action(self):
		""" Generates and returns Action instance """
		cbHoldFeedback = self.builder.get_object("cbHoldFeedback")
		sclHoldFeedback = self.builder.get_object("sclHoldFeedback")
		normalaction = self._save_modemod(0)
		holdaction = self._save_modemod(1)
		dblaction = self._save_modemod(2)
		if dblaction:
			action = DoubleclickModifier(dblaction, normalaction)
			action.holdaction = holdaction
		elif holdaction:
			action = HoldModifier(holdaction, normalaction)
		else:
			action = normalaction
		action.timeout = self.builder.get_object("adjTime").get_value()
		
		if cbHoldFeedback.get_active():
			action = FeedbackModifier(HapticPos.BOTH,
						sclHoldFeedback.get_value(), action)
		
		return action
	
	
	def _save_modemod(self, index):
		""" Generates ModeModifier from page in Notebook """
		adjSoftLevel = self.builder.get_object("adjSoftLevel")
		pars = []
		for item, action, l, b, clearb in self.actions[index]:
			if isinstance(item, RangeOP) and item.value == -1:
				# Value taken from slider
				item.value = adjSoftLevel.get_value()
			pars += [ item, action ]
		if self.nomods[index]:
			pars += [ self.nomods[index] ]
		action = ModeModifier(*pars)
		if len(pars) == 0:
			# No action is actually set
			action = NoAction()
		elif len(pars) == 1:
			# Only default action left
			action = self.nomods[index]
		return action
	
	
	def _load_modemod(self, index, action):
		for key in action.mods:
			self._add_action(index, key, action.mods[key])
	
	
	def _set_nomod_button(self, index, action):
		if isinstance(action, ModeModifier):
			self._load_modemod(index, action)
			self.nomods[index] = action.default
		else:
			self.nomods[index] = action
		actionButton = self.action_widgets[index][1]
		actionButton.set_label(self.nomods[index].describe(self.mode))
	
	
	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)
예제 #36
0
 def _get_axis_description(self):
     axis, neg, pos = "%s %s" % (self.id.name,
                                 _("Axis")), _("Negative"), _("Positive")
     if self.id in AxisAction.AXIS_NAMES:
         axis, neg, pos = [_(x) for x in AxisAction.AXIS_NAMES[self.id]]
     return axis, neg, pos
예제 #37
0
	def describe(self):
		return self.label + "  " + _(">>")
예제 #38
0
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')),
        (None, None),
        (SCButtons.LPADTOUCH, _('Left Pad Touched')),
        (SCButtons.RPADTOUCH, _('Right Pad Touched')),
        (SCButtons.LPAD, _('Left Pad Pressed')),
        (SCButtons.RPAD, _('Right Pad Pressed')),
        (None, None),
        (SCButtons.LGRIP, _('Left Grip')),
        (SCButtons.RGRIP, _('Right Grip')),
        (None, None),
        (SCButtons.A, _('A')),
        (SCButtons.B, _('B')),
        (SCButtons.X, _('X')),
        (SCButtons.Y, _('Y')),
        (None, None),
        (SCButtons.BACK, _('Back (select)')),
        (SCButtons.C, _('Center')),
        (SCButtons.START, _('Start')),
    )

    def __init__(self, app, editor):
        AEComponent.__init__(self, app, editor)
        self._recursing = False
        self.parser = GuiActionParser()

    def load(self):
        if self.loaded: return
        AEComponent.load(self)
        self._recursing = True
        cbGyroButton = self.builder.get_object("cbGyroButton")
        fill_buttons(cbGyroButton)
        self._recursing = False

    def set_action(self, mode, action):
        if self.handles(mode, action):
            if isinstance(action, NoAction):
                self.select_gyro_output("none")
                self.select_gyro_button(None)
                return
            if isinstance(action, ModeModifier):
                b = action.order[0]
                action = action.mods[b]
                self.select_gyro_button(b)
            else:
                self.select_gyro_button(None)
            if isinstance(action, MouseAction):
                self.select_gyro_output("mouse")
                if len(action.parameters) >= 2 and action.parameters[1] == YAW:
                    self.select_yaw_roll(YAW)
                else:
                    self.select_yaw_roll(ROLL)
            elif isinstance(action, GyroAction):
                ap = action.parameters
                if len(ap) == 2:
                    self.select_yaw_roll(YAW)
                else:
                    self.select_yaw_roll(ROLL)
                if ap[0] == Axes.ABS_X and ap[-1] == Axes.ABS_Y:
                    if isinstance(action, GyroAbsAction):
                        self.select_gyro_output("left_abs")
                    else:
                        self.select_gyro_output("left")
                    self.select_yaw_roll(ROLL)
                elif ap[0] == Axes.ABS_RX and ap[-1] == Axes.ABS_RY:
                    if isinstance(action, GyroAbsAction):
                        self.select_gyro_output("right_abs")
                    else:
                        self.select_gyro_output("right")
                    self.select_yaw_roll(ROLL)

    def get_button_title(self):
        return _("Joystick or Mouse")

    def handles(self, mode, action):
        if isinstance(action, NoAction):
            return True
        if is_gyro_enable(action):
            action = action.mods[action.order[0]]
        if isinstance(action, GyroAction):  # Takes GyroAbsAction as well
            ap = action.parameters
            if (len(ap) == 3 and not ap[1]) or len(ap) == 2:
                if ap[0] == Axes.ABS_X and ap[-1] == Axes.ABS_Y:
                    return True
                if ap[0] == Axes.ABS_RX and ap[-1] == Axes.ABS_RY:
                    return True
            return False
        if isinstance(action, MultiAction):
            return False
        return True

    def select_gyro_output(self, key):
        """ Just sets combobox value """
        cb = self.builder.get_object("cbMode")
        model = cb.get_model()
        self._recursing = True
        for row in model:
            if key == row[2]:
                cb.set_active_iter(row.iter)
                self._recursing = False
                return
        self._recursing = False

    def select_yaw_roll(self, yawroll):
        """ Just sets combobox value """
        cb = self.builder.get_object("cbYawRoll")
        model = cb.get_model()
        self._recursing = True
        for row in model:
            if yawroll == row[0]:
                cb.set_active_iter(row.iter)
                self._recursing = False
                return
        self._recursing = False

    def select_gyro_button(self, button):
        """ Just sets combobox value """
        cb = self.builder.get_object("cbGyroButton")
        model = cb.get_model()
        self._recursing = True
        if button is not None:
            button = button.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

    def update(self, *a):
        pass

    def send(self, *a):
        if self._recursing: return

        cbMode = self.builder.get_object("cbMode")
        cbYawRoll = self.builder.get_object("cbYawRoll")
        cbGyroButton = self.builder.get_object("cbGyroButton")
        action = cbMode.get_model().get_value(cbMode.get_active_iter(), 0)
        yawroll = cbYawRoll.get_model().get_value(cbYawRoll.get_active_iter(),
                                                  0)
        button = cbGyroButton.get_model().get_value(
            cbGyroButton.get_active_iter(), 0)

        match = re.match(r"([^\[]+)\[([^\|]+)\|([^\]]+)\](.*)", action)
        if match:
            grps = match.groups()
            if yawroll == YAW:
                action = "%s%s%s" % (grps[0], grps[1], grps[3])
            else:
                action = "%s%s%s" % (grps[0], grps[2], grps[3])
        action = self.parser.restart(action).parse()

        if button:
            action = ModeModifier(getattr(SCButtons, button), action)

        self.editor.set_action(action)
예제 #39
0
 def get_button_title(self):
     return _("Joystick or Mouse")
예제 #40
0
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') ),
		(None, None),
		(SCButtons.LPADTOUCH,	_('Left Pad Touched') ),
		(SCButtons.RPADTOUCH,	_('Right Pad Touched') ),
		(SCButtons.LPAD,		_('Left Pad Pressed') ),
		(SCButtons.RPAD,		_('Right Pad Pressed') ),
		(None, None),
		(SCButtons.LGRIP,		_('Left Grip') ),
		(SCButtons.RGRIP,		_('Right Grip') ),
		(STICK,					_('Stick Tilted') ),
		(None, None),
		(SCButtons.A,			_('A') ),
		(SCButtons.B,			_('B') ),
		(SCButtons.X,			_('X') ),
		(SCButtons.Y,			_('Y') ),
		(None, None),
		(SCButtons.BACK,		_('Back (select)') ),
		(SCButtons.C,			_('Center') ),
		(SCButtons.START,		_('Start') ),
	)
	
	def __init__(self, app, editor):
		AEComponent.__init__(self, app, editor)
		self._recursing = False
		self.parser = GuiActionParser()
	
	
	def load(self):
		if self.loaded : return
		AEComponent.load(self)
		self._recursing = True
		cbGyroButton = self.builder.get_object("cbGyroButton")
		fill_buttons(cbGyroButton)
		self._recursing = False
	
	
	def set_action(self, mode, action):
		if self.handles(mode, action):
			if isinstance(action, NoAction):
				self.select_gyro_output("none")
				self.select_gyro_button(SCButtons.RPADTOUCH)
				return
			if isinstance(action, ModeModifier):
				self._recursing = True
				self.builder.get_object("cbInvertGyro").set_active(bool(action.default))
				self._recursing = False
				b = action.mods.keys()[0]
				action = action.mods[b] or action.default
				self.select_gyro_button(b)
			else:
				self.select_gyro_button(None)
			if isinstance(action, SensitivityModifier) and isinstance(action.action, MouseAction):
				# Mouse (Desktop)
				self.select_gyro_output("mouse")
				if len(action.action.parameters) > 0 and action.action.parameters[0] == YAW:
					self.select_yaw_roll(YAW)
				else:
					self.select_yaw_roll(ROLL)
				self.editor.set_default_sensitivity(3.5, 3.5, 3.5)
				self.editor.set_sensitivity(*action.speeds)
			elif isinstance(action, MouseAction):
				# Mouse (Camera)
				self.select_gyro_output("mouse_cam")
				if len(action.parameters) > 0 and action.parameters[0] == YAW:
					self.select_yaw_roll(YAW)
				else:
					self.select_yaw_roll(ROLL)
			elif isinstance(action, GyroAction):
				ap = action.parameters
				if len(ap) == 2:
					self.select_yaw_roll(YAW)
				else:
					self.select_yaw_roll(ROLL)
				if ap[0] == Axes.ABS_X and ap[-1] == Axes.ABS_Y:
					if isinstance(action, GyroAbsAction):
						self.select_gyro_output("left_abs")
					else:
						self.select_gyro_output("left")
				elif ap[0] == Axes.ABS_RX and ap[-1] == Axes.ABS_RY:
					if isinstance(action, GyroAbsAction):
						self.select_gyro_output("right_abs")
					else:
						self.select_gyro_output("right")
				elif ap[0] == Rels.REL_Y and ap[-1] == Rels.REL_X:
					self.select_gyro_output("mouse_stick")
			self.modifier_updated()
	
	
	def modifier_updated(self):
		cbInvertY = self.builder.get_object("cbInvertY")
		sens = self.editor.get_sensitivity()
		inverted = len(sens) >= 2 and sens[1] < 0
		if cbInvertY.get_active() != inverted:
			self._recursing = True
			cbInvertY.set_active(inverted)
			self._recursing = False
	
	
	def cbInvertY_toggled_cb(self, cb, *a):
		if self._recursing: return
		sens = list(self.editor.get_sensitivity())
		# Ensure that editor accepts Y sensitivity
		if len(sens) >= 2:
			sens[1] = abs(sens[1])
			if cb.get_active():
				# Ensure that Y sensitivity is negative
				sens[1] *= -1
		self.editor.set_sensitivity(*sens)
	
	
	def get_button_title(self):
		return _("Joystick or Mouse")
	
	
	def handles(self, mode, action):
		if isinstance(action, NoAction):
			return True
		if is_gyro_enable(action):
			action = action.mods.values()[0] or action.default
			if isinstance(action, SensitivityModifier):
				action = action.action
		if isinstance(action, GyroAction):	# Takes GyroAbsAction as well
			ap = action.parameters
			if (len(ap) == 3 and not ap[1]) or len(ap) == 2:
				if ap[0] == Axes.ABS_X and ap[-1] == Axes.ABS_Y:
					return True
				elif ap[0] == Axes.ABS_RX and ap[-1] == Axes.ABS_RY:
					return True
				elif ap[0] == Rels.REL_Y and ap[-1] == Rels.REL_X:
					return True
			return False
		if isinstance(action, (MouseAction, MouseAbsAction)):
			return True
		return False
	
	
	def select_gyro_output(self, key):
		""" Just sets combobox value """
		cb = self.builder.get_object("cbMode")
		model = cb.get_model()
		self._recursing = True
		for row in model:
			if key == row[2]:
				cb.set_active_iter(row.iter)
				self._recursing = False
				return
		self._recursing = False
	
	
	def select_yaw_roll(self, yawroll):
		""" Just sets combobox value """
		cb = self.builder.get_object("cbYawRoll")
		model = cb.get_model()
		self._recursing = True
		for row in model:
			if yawroll == row[0]:
				cb.set_active_iter(row.iter)
				self._recursing = False
				return
		self._recursing = False
	
	
	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")
		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)
		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
	
	
	def on_cbInvertGyro_toggled(self, cb, *a):
		lblGyroEnable = self.builder.get_object("lblGyroEnable")
		if cb.get_active():
			lblGyroEnable.set_label(_("Gyro Disable Button"))
		else:
			lblGyroEnable.set_label(_("Gyro Enable Button"))
		if not self._recursing:
			self.send()
	
	
	def on_sclSoftLevel_format_value(self, scale, value):
		return  "%s%%" % (int(value * 100.0),)
	
	
	def update(self, *a):
		pass
	
	
	def hidden(self):
		self.editor.set_default_sensitivity(1, 1, 1)
	
	
	def send(self, *a):
		if self._recursing : return
		
		cbMode = self.builder.get_object("cbMode")
		cbYawRoll = self.builder.get_object("cbYawRoll")
		rvSoftLevel = self.builder.get_object("rvSoftLevel")
		sclSoftLevel = self.builder.get_object("sclSoftLevel")
		cbGyroButton = self.builder.get_object("cbGyroButton")
		cbInvertGyro = self.builder.get_object("cbInvertGyro")
		action = cbMode.get_model().get_value(cbMode.get_active_iter(), 0)
		key = cbMode.get_model().get_value(cbMode.get_active_iter(), 2)
		yawroll = cbYawRoll.get_model().get_value(cbYawRoll.get_active_iter(), 0)
		item = cbGyroButton.get_model().get_value(cbGyroButton.get_active_iter(), 0)
		rvSoftLevel.set_reveal_child(item in TRIGGERS)
		
		match = re.match(r"([^\[]+)\[([^\|]+)\|([^\]]+)\](.*)", action)
		if match:
			grps = match.groups()
			if yawroll == YAW:
				action = "%s%s%s" % (grps[0], grps[1], grps[3])
			else:
				action = "%s%s%s" % (grps[0], grps[2], grps[3])
		action = self.parser.restart(action).parse()
		
		if item and action:
			if item in TRIGGERS:
				what = RangeOP(getattr(SCButtons, item), ">=", sclSoftLevel.get_value())
			elif item == STICK:
				what = RangeOP(item, ">=", sclSoftLevel.get_value())
			else:
				what = getattr(SCButtons, item)
			if cbInvertGyro.get_active():
				action = ModeModifier(what, NoAction(), action)
			else:
				action = ModeModifier(what, action)
		if key == "mouse":
			self.editor.set_default_sensitivity(3.5, 3.5, 3.5)
		else:
			self.editor.set_default_sensitivity(1, 1, 1)
		
		self.editor.set_action(action)
예제 #41
0
class StatusIcon(GObject.GObject):
    """
	Base class for all status icon backends
	"""
    TRAY_TITLE = _("Syncthing")

    __gsignals__ = {
        b"clicked": (GObject.SIGNAL_RUN_FIRST, None, ()),
    }

    __gproperties__ = {
        b"active":
        (GObject.TYPE_BOOLEAN, "is the icon user-visible?",
         "does the icon back-end think that anything is might be shown to the user?",
         True, GObject.PARAM_READWRITE)
    }

    def __init__(self, icon_path, popupmenu, force=False):
        GObject.GObject.__init__(self)
        self.__icon_path = os.path.normpath(os.path.abspath(icon_path))
        self.__popupmenu = popupmenu
        self.__active = True
        self.__visible = False
        self.__hidden = False
        self.__icon = "si-syncthing-unknown"
        self.__text = ""
        self.__force = force

    def get_active(self):
        """
		Return whether there is at least a chance that the icon might be shown to the user
		
		If this returns `False` then the icon will definetely not be shown, but if it returns `True` it doesn't have to
		be visible...
		
		<em>Note:</em> This value is not directly influenced by calling `hide()` and `show()`.
		
		@return {bool}
		"""
        return self.get_property("active")

    def set(self, icon=None, text=None):
        """
		Set the status icon image and descriptive text
		
		If either of these are `None` their previous value will be used.
		
		@param {String} icon
		       The name of the icon to show (i.e. `si-syncthing-idle`)
		@param {String} text
		       Some text that indicates what the application is currently doing (generally this be used for the tooltip)
		"""
        if not icon.endswith("-0"):  # si-syncthing-0
            # Ignore first syncing icon state to prevent the icon from flickering
            # into the main notification bar during initialization
            self.__visible = True

        if self.__hidden:
            self._set_visible(False)
        else:
            self._set_visible(self.__visible)

    def hide(self):
        """
		Hide the icon
		
		This method tries its best to ensure the icon is hidden, but there are no guarantees as to how use well its
		going to work.
		"""
        self.__hidden = True
        self._set_visible(False)

    def show(self):
        """
		Show a previously hidden icon
		
		This method tries its best to ensure the icon is hidden, but there are no guarantees as to how use well its
		going to work.
		"""
        self.__hidden = False
        self._set_visible(self.__visible)

    def is_clickable(self):
        """ Basically, returns False is appindicator is used """
        return True

    def _is_forced(self):
        return self.__force

    def _on_click(self, *a):
        self.emit("clicked")

    def _get_icon(self, icon=None):
        """
		@internal
		
		Use `set()` instead.
		"""
        if icon:
            self.__icon = icon
        return self.__icon

    def _get_text(self, text=None):
        """
		@internal
		
		Use `set()` instead.
		"""
        if text:
            self.__text = text
        return self.__text

    def _get_popupmenu(self):
        """
		@internal
		"""
        return self.__popupmenu

    def _set_visible(self, visible):
        """
		@internal
		"""
        pass

    def do_get_property(self, property):
        if property.name == "active":
            return self.__active
        else:
            raise AttributeError("Unknown property %s" % property.name)

    def do_set_property(self, property, value):
        if property.name == "active":
            self.__active = value
        else:
            raise AttributeError("unknown property %s" % property.name)
예제 #42
0
 def _bad_id_duplicate(self, *a):
     self.builder.get_object("lblNope").set_label(
         _('Invalid Menu ID: Menu with same ID already exists.'))
     self.builder.get_object("rvInvalidID").set_reveal_child(True)
     self.builder.get_object("btSave").set_sensitive(False)
예제 #43
0
 def get_button_title(self):
     return _("Per Axis")
예제 #44
0
class ModeshiftEditor(Editor):
    GLADE = "modeshift_editor.glade"
    BUTTONS = (  # in order as displayed in combobox
        (SCButtons.A, _('A')),
        (SCButtons.B, _('B')),
        (SCButtons.X, _('X')),
        (SCButtons.Y, _('Y')),
        (None, None),
        (SCButtons.BACK, _('Back (select)')),
        (SCButtons.C, _('Center')),
        (SCButtons.START, _('Start')),
        (None, None),
        (SCButtons.LGRIP, _('Left Grip')),
        (SCButtons.RGRIP, _('Right Grip')),
        (None, None),
        (SCButtons.LB, _('Left Bumper')),
        (SCButtons.RB, _('Right Bumper')),
        (SCButtons.LT, _('Left Trigger')),
        (SCButtons.RT, _('Right Trigger')),
        (None, None),
        (SCButtons.LPAD, _('Left Pad Pressed')),
        (SCButtons.RPAD, _('Right Pad Pressed')),
        (SCButtons.LPADTOUCH, _('Left Pad Touched')),
        (SCButtons.RPADTOUCH, _('Right Pad Touched')),
    )

    def __init__(self, app, callback):
        self.app = app
        self.id = None
        self.mode = Action.AC_BUTTON
        self.ac_callback = callback
        self.current_page = 0
        self.actions = ([], [], [])
        self.nomods = [NoAction(), NoAction(), NoAction()]
        self.setup_widgets()

    def setup_widgets(self):
        Editor.setup_widgets(self)

        cbButtonChooser = self.builder.get_object("cbButtonChooser")
        cbButtonChooser.set_row_separator_func(
            lambda model, iter: model.get_value(iter, 0) is None)

        b = lambda a: self.builder.get_object(a)
        self.action_widgets = (
            # Order goes: Grid, 1st Action Button, Clear Button
            # 1st group, 'pressed'
            (b('grActions'), b('btDefault'), b('btClearDefault')),
            # 2nd group, 'hold'
            (b('grHold'), b('btHold'), b('btClearHold')),
            # 2nd group, 'double-click'
            (b('grDoubleClick'), b('btDoubleClick'), b('btClearDoubleClick')),
        )

        self._fill_button_chooser()
        headerbar(self.builder.get_object("header"))

    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
            model.append((None if button is None else button.name, text))
        cbButtonChooser.set_active(0)

    def _add_action(self, index, button, action):
        grActions = self.action_widgets[index][0]
        cbButtonChooser = self.builder.get_object("cbButtonChooser")
        model = cbButtonChooser.get_model()

        for row in model:
            if model.get_value(row.iter, 0) == button.name:
                model.remove(row.iter)
                break
        try:
            while model.get_value(model[0].iter, 0) is None:
                model.remove(model[0].iter)
            cbButtonChooser.set_active(0)
        except:
            pass

        i = len(self.actions[index]) + 1
        l = Gtk.Label()
        l.set_markup("<b>%s</b>" % (button.name, ))
        l.set_xalign(0.0)
        b = Gtk.Button.new_with_label(action.describe(self.mode))
        b.set_property("hexpand", True)
        b.connect('clicked', self.on_actionb_clicked, index, button)
        clearb = Gtk.Button()
        clearb.set_image(
            Gtk.Image.new_from_stock("gtk-delete", Gtk.IconSize.SMALL_TOOLBAR))
        clearb.set_relief(Gtk.ReliefStyle.NONE)
        clearb.connect('clicked', self.on_clearb_clicked, index, button)
        grActions.attach(l, 0, i, 1, 1)
        grActions.attach(b, 1, i, 1, 1)
        grActions.attach(clearb, 2, i, 1, 1)

        self.actions[index].append([button, action, l, b, clearb])
        grActions.show_all()

    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 button.name, text))
            if button is not None:
                if button.name == active:
                    index = i
            i += 1
        # Reselect formely active item
        if index >= 0:
            cbButtonChooser.set_active(index)

    def _choose_editor(self, action, cb):
        if isinstance(action, Macro):
            from scc.gui.macro_editor import MacroEditor  # Cannot be imported @ top
            e = MacroEditor(self.app, cb)
            e.set_title(_("Edit Macro"))
        else:
            from scc.gui.action_editor import ActionEditor  # Cannot be imported @ top
            e = ActionEditor(self.app, cb)
            e.set_title(_("Edit Action"))
            e.hide_modeshift()
        return e

    def on_actionb_clicked(self, trash, index, clicked_button):
        for i in self.actions[index]:
            button, action, l, b, clearb = i
            if button == clicked_button:

                def on_chosen(id, action):
                    b.set_label(action.describe(self.mode))
                    i[1] = action

                ae = self._choose_editor(action, on_chosen)
                ae.set_input(self.id, action, mode=self.mode)
                ae.show(self.window)
                return

    def on_ntbMore_switch_page(self, ntb, box, index):
        self.current_page = index
        self._fill_button_chooser()
        self.builder.get_object("cbButtonChooser").set_sensitive(
            box.get_sensitive())
        self.builder.get_object("btAddAction").set_sensitive(
            box.get_sensitive())

    def on_nomodbt_clicked(self, button, *a):
        actionButton = self.action_widgets[self.current_page][1]

        def on_chosen(id, action):
            actionButton.set_label(action.describe(self.mode))
            self.nomods[self.current_page] = action

        ae = self._choose_editor(self.nomods[self.current_page], on_chosen)
        ae.set_input(self.id, self.nomods[self.current_page], mode=self.mode)
        ae.show(self.window)

    def on_nomodclear_clicked(self, button, *a):
        self.nomods[self.current_page] = NoAction()
        actionButton = self.action_widgets[self.current_page][1]
        actionButton.set_label(self.nomods[self.current_page].describe(
            self.mode))

    def on_btAddAction_clicked(self, *a):
        cbButtonChooser = self.builder.get_object("cbButtonChooser")
        b = getattr(
            SCButtons,
            cbButtonChooser.get_model().get_value(
                cbButtonChooser.get_active_iter(), 0))
        self._add_action(self.current_page, b, NoAction())

    def on_btClear_clicked(self, *a):
        """ Handler for clear button """
        action = NoAction()
        if self.ac_callback is not None:
            self.ac_callback(self.id, action)
        self.close()

    def on_btCustomActionEditor_clicked(self, *a):
        """ Handler for 'Custom Editor' button """
        from scc.gui.action_editor import ActionEditor  # Can't be imported on top
        e = ActionEditor(self.app, self.ac_callback)
        e.set_input(self.id, self._make_action(), mode=self.mode)
        e.hide_action_buttons()
        e.hide_advanced_settings()
        e.set_title(self.window.get_title())
        e.force_page(e.load_component("custom"), True)
        self.close()
        e.show(self.get_transient_for())

    def on_btOK_clicked(self, *a):
        """ Handler for OK button """
        if self.ac_callback is not None:
            self.ac_callback(self.id, self._make_action())
        self.close()

    def _make_action(self):
        """ Generates and returns Action instance """
        normalaction = self._save_modemod(0)
        holdaction = self._save_modemod(1)
        dblaction = self._save_modemod(2)
        if dblaction:
            action = DoubleclickModifier(dblaction, normalaction)
            action.holdaction = holdaction
        elif holdaction:
            action = HoldModifier(holdaction, normalaction)
        else:
            action = normalaction
        action.timeout = self.builder.get_object("adjTime").get_value()
        return action

    def _save_modemod(self, index):
        """ Generates ModeModifier from page in Notebook """
        pars = []
        # TODO: Other pages
        for button, action, l, b, clearb in self.actions[index]:
            pars += [button, action]
        if self.nomods[index]:
            pars += [self.nomods[index]]
        action = ModeModifier(*pars)
        if len(pars) == 0:
            # No action is actually set
            action = NoAction()
        elif len(pars) == 1:
            # Only default action left
            action = self.nomods[index]
        return action

    def _load_modemod(self, index, action):
        for key in action.mods:
            self._add_action(index, key, action.mods[key])

    def _set_nomod_button(self, index, action):
        if isinstance(action, ModeModifier):
            self._load_modemod(index, action)
            self.nomods[index] = action.default
        else:
            self.nomods[index] = action
        actionButton = self.action_widgets[index][1]
        actionButton.set_label(self.nomods[index].describe(self.mode))

    def set_input(self, id, action, mode=Action.AC_BUTTON):
        btDefault = self.builder.get_object("btDefault")
        self.id = id
        self.mode = mode

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

        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)
예제 #45
0
 def describe(self, context):
     if self.name: return self.name
     return _("Mouse Region")
예제 #46
0
 def describe(self, context):
     return _("(not set)")
예제 #47
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)
예제 #48
0
 def get_button_title(self):
     return _("On-Screen Keyboard")
예제 #49
0
 def grab_action(self, action, cb):
     b = SimpleChooser(self.app, "axis", cb)
     b.set_title(_("Select Axis"))
     area = action_to_area(action)
     b.display_action(Action.AC_STICK, area)
     b.show(self.editor.window)
예제 #50
0
 def get_button_title(self):
     return _("Special Action")
	def get_button_title(self):
		return _("Recent List")
예제 #52
0
	def generate(self, menuhandler):
		return _("[ %s Recent Profiles ]") % (self.rows,)
예제 #53
0
	def describe(self):
		if self.label:
			return _("----[ %s ]----") % (self.label,)
		else:
			return _("---- Separator ----")
예제 #54
0
 def get_button_title(self):
     return _("Menu")
예제 #55
0
 def update(self):
     if self.id in TRIGGERS and self.id in self.app.current.triggers:
         self.label.set_label(self.app.current.triggers[self.id].describe(
             self.ACTION_CONTEXT))
     else:
         self.label.set_label(_("(no action)"))
예제 #56
0
 def update(self):
     self.label.set_label(_("(no action)"))
예제 #57
0
 def get_button_title(self):
     return _("Key or Button")
예제 #58
0
	def on_btAnalog_clicked(self, *a):
		""" 'Analog Output' handler """
		b = SimpleChooser(self.app, "axis", lambda action: self.on_action_chosen("analog", action) )
		b.set_title(_("Select Analog Axis"))
		b.display_action(Action.AC_STICK, AxisAction(self.analog))
		b.show(self.editor.window)
예제 #59
0
	def check(self):
		""" Performs various (three) checks and reports possible problems """
		# TODO: Maybe not best place to do this
		try:
			# Dynamic modules
			rawlist = file("/proc/modules", "r").read().split("\n")
			kernel_mods = [ line.split(" ")[0] for line in rawlist ]
			# Built-in modules
			release = platform.uname()[2]
			rawlist = file("/lib/modules/%s/modules.builtin" % release, "r").read().split("\n")
			kernel_mods += [ os.path.split(x)[-1].split(".")[0] for x in rawlist ]
		except Exception:
			# Maybe running on BSD or Windows...
			kernel_mods = [ ]
		
		if len(kernel_mods) > 0 and "uinput" not in kernel_mods:
			# There is no uinput
			msg = _('uinput kernel module not loaded')
			msg += "\n\n" + _('Please, consult your distribution manual on how to enable uinput')
			msg += "\n"   + _('or click on "Fix Temporary" button to attempt fix that should work until next restart.')
			ribar = self.show_error(msg)
			gksudo = find_gksudo()
			modprobe = find_binary("modprobe")
			if gksudo and not hasattr(ribar, "_fix_tmp"):
				button = Gtk.Button.new_with_label(_("Fix Temporary"))
				ribar._fix_tmp = button
				button.connect('clicked', self.apply_temporary_fix,
					gksudo + [modprobe, "uinput"],
					_("This will load missing uinput module.")
				)
				ribar.add_button(button, -1)
			return True
		elif not os.path.exists("/dev/uinput"):
			# /dev/uinput missing
			msg = _('/dev/uinput doesn\'t exists')
			msg += "\n" + _('uinput kernel module is loaded, but /dev/uinput is missing.')
			#msg += "\n\n" + _('Please, consult your distribution manual on what in the world could cause this.')
			msg += "\n\n" + _('Please, consult your distribution manual on how to enable uinput')
			self.show_error(msg)
			return True
		elif not check_access("/dev/uinput"):
			# Cannot acces uinput
			msg = _('You don\'t have required access to /dev/uinput.')
			msg += "\n"   + _('This will most likely prevent emulation from working.')
			msg += "\n\n" + _('Please, consult your distribution manual on how to enable uinput')
			msg += "\n"   + _('or click on "Fix Temporary" button to attempt fix that should work until next restart.')
			ribar = self.show_error(msg)
			gksudo = find_gksudo()
			if gksudo and not hasattr(ribar, "_fix_tmp"):
				button = Gtk.Button.new_with_label(_("Fix Temporary"))
				ribar._fix_tmp = button
				button.connect('clicked', self.apply_temporary_fix,
					gksudo + ["chmod", "666", "/dev/uinput"],
					_("This will enable input emulation for <i>every application</i> and <i>all users</i> on this machine.")
				)
				ribar.add_button(button, -1)
			return True
		return False
예제 #60
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()