def enable_osd_mode(self): # TODO: Support for multiple controllers here self.osd_mode_controller = 0 osd_mode_profile = Profile(GuiActionParser()) osd_mode_profile.load(find_profile(App.OSD_MODE_PROF_NAME)) try: c = self.dm.get_controllers()[self.osd_mode_controller] except IndexError: log.error("osd_mode: Controller not connected") self.quit() return def on_lock_failed(*a): log.error("osd_mode: Locking failed") self.quit() def on_lock_success(*a): log.debug("osd_mode: Locked everything") from scc.gui.osd_mode_mapper import OSDModeMapper self.osd_mode_mapper = OSDModeMapper(osd_mode_profile) self.osd_mode_mapper.set_target_window(self.window.get_window()) GLib.timeout_add(10, self.osd_mode_mapper.run_scheduled) # Locks everything but pads. Pads are emulating mouse and this is # better left in daemon - involving socket in mouse controls # adds too much lags. c.lock(on_lock_success, on_lock_failed, 'A', 'B', 'X', 'Y', 'START', 'BACK', 'LB', 'RB', 'C', 'LPAD', 'RPAD', 'STICK', 'LGRIP', 'RGRIP', 'LT', 'RT', 'STICKPRESS') # Ask daemon to temporaly reconfigure pads for mouse emulation c.replace(DaemonManager.nocallback, on_lock_failed, LEFT, osd_mode_profile.pads[LEFT]) c.replace(DaemonManager.nocallback, on_lock_failed, RIGHT, osd_mode_profile.pads[RIGHT])
def load_osk(self): cbStickAction = self.builder.get_object("cbStickAction") cbTriggersAction = self.builder.get_object("cbTriggersAction") profile = Profile(GuiActionParser()) profile.load(find_profile(OSDKeyboard.OSK_PROF_NAME)) self._recursing = True # Load triggers triggers = "%s|%s" % ( profile.triggers[LEFT].to_string(), profile.triggers[RIGHT].to_string() ) if not self.set_cb(cbTriggersAction, triggers, keyindex=1): self.add_custom(cbTriggersAction, triggers) # Load stick if not self.set_cb(cbStickAction, profile.stick.to_string(), keyindex=1): self.add_custom(cbStickAction, profile.stick.to_string()) # Load sensitivity s = profile.pads[LEFT].compress().speed self.builder.get_object("sclSensX").set_value(s[0]) self.builder.get_object("sclSensY").set_value(s[1]) self._recursing = False
def _load_osk_profile(self): """ Loads and returns on-screen keyboard profile. Used by methods that are changing it. """ profile = Profile(GuiActionParser()) profile.load(find_profile(OSDKeyboard.OSK_PROF_NAME)) return profile
def __init__(self, app): BindingEditor.__init__(self, app) self.app = app self.gladepath = app.gladepath self.imagepath = app.imagepath self.current = Profile(GuiActionParser()) self.current.load(find_profile(OSDKeyboard.OSK_PROF_NAME)) self.setup_widgets()
def load_profile(self, giofile): """ Loads profile from 'giofile' into 'profile' object Calls on_profiles_loaded when done """ # This may get asynchronous later, but that load runs under 1ms... profile = Profile(GuiActionParser()) profile.load(giofile.get_path()) self.on_profile_loaded(profile, giofile)
def export_profile(tar, filename): profile = Profile(TalkingActionParser()) try: out = tempfile.NamedTemporaryFile() profile.load(filename) profile.save(out.name) tar.add(out.name, arcname=os.path.split(filename)[-1], recursive=False) except Exception, e: # Profile that cannot be parsed shouldn't be exported log.error(e) return False
def _export(self, giofile, target_filename): """ Performs actual exporting. This method is used when only profile with no referenced files is to be exported and works pretty simple - load, parse, save in new file. """ profile = Profile(TalkingActionParser()) try: profile.load(giofile.get_path()) except Exception, e: # Profile that cannot be parsed shouldn't be exported log.error(e) return False
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 _add_refereced_profile(self, model, giofile, used): """ Loads profile file and recursively adds all profiles and menus referenced by it into 'package' list. Returns True on success or False if something cannot be parsed. """ # Load & parse selected profile and check every action in it profile = Profile(ActionParser()) try: profile.load(giofile.get_path()) except Exception, e: # Profile that cannot be parsed shouldn't be exported log.error(e) return False
def import_scc(self, filename): """ Imports simple, single-file scc-profile. Just loads it, checks for shell() actions and asks user to enter name. """ files = self.builder.get_object("lstImportPackage") # Load profile profile = Profile(GuiActionParser()) try: profile.load(filename) except Exception, e: # Profile cannot be parsed. Display error message and let user to quit # Error message reuses page from VDF import, because they are # basically the same log.error(e) self.error(str(e)) return
def __init__(self): OSDWindow.__init__(self, "osd-keyboard") TimerManager.__init__(self) self.daemon = None self.mapper = None self.keymap = Gdk.Keymap.get_default() self.keymap.connect('state-changed', self.on_state_changed) self.profile = Profile(TalkingActionParser()) kbimage = os.path.join(get_config_path(), 'keyboard.svg') if not os.path.exists(kbimage): # Prefer image in ~/.config/scc, but load default one as fallback kbimage = os.path.join(get_share_path(), "images", 'keyboard.svg') self.background = SVGWidget(self, kbimage) self.limits = {} self.limits[LEFT] = self.background.get_rect_area( self.background.get_element("LIMIT_LEFT")) self.limits[RIGHT] = self.background.get_rect_area( self.background.get_element("LIMIT_RIGHT")) cursor = os.path.join(get_share_path(), "images", 'menu-cursor.svg') self.cursors = {} self.cursors[LEFT] = Gtk.Image.new_from_file(cursor) self.cursors[LEFT].set_name("osd-keyboard-cursor") self.cursors[RIGHT] = Gtk.Image.new_from_file(cursor) self.cursors[RIGHT].set_name("osd-keyboard-cursor") self._eh_ids = [] self._stick = 0, 0 self._hovers = {self.cursors[LEFT]: None, self.cursors[RIGHT]: None} self._pressed = {self.cursors[LEFT]: None, self.cursors[RIGHT]: None} self.c = Gtk.Box() self.c.set_name("osd-keyboard-container") self.f = Gtk.Fixed() self.f.add(self.background) self.f.add(self.cursors[LEFT]) self.f.add(self.cursors[RIGHT]) self.c.add(self.f) self.add(self.c) self.timer('labels', 0.1, self.update_labels)
def wrapper(*a): _time = time.time def fake_time(): return fake_time.t def add(n): fake_time.t += n fake_time.t = _time() fake_time.add = add time.time = fake_time controller = FakeController(0) profile = Profile(parser) scheduler = Scheduler() mapper = Mapper(profile, scheduler, keyboard=False, mouse=False, gamepad=False, poller=None) mapper.keyboard = RememberingDummy() mapper.gamepad = RememberingDummy() mapper.mouse = RememberingDummy() mapper.set_controller(controller) mapper._testing = True mapper._tick_rate = 0.01 _mapper_input = mapper.input def mapper_input(*a): add(mapper._tick_rate) _mapper_input(*a) scheduler.run() mapper.input = mapper_input a = list(a) + [mapper] try: return fn(*a) finally: time.time = _time
def __init__(self, config=None): self.kbimage = os.path.join(get_config_path(), 'keyboard.svg') if not os.path.exists(self.kbimage): # Prefer image in ~/.config/scc, but load default one as fallback self.kbimage = os.path.join(get_share_path(), "images", 'keyboard.svg') TimerManager.__init__(self) OSDWindow.__init__(self, "osd-keyboard") self.daemon = None self.mapper = None self.keymap = Gdk.Keymap.get_default() self.keymap.connect('state-changed', self.on_keymap_state_changed) Action.register_all(sys.modules['scc.osd.osk_actions'], prefix="OSK") self.profile = Profile(TalkingActionParser()) self.config = config or Config() self.dpy = X.Display(hash(GdkX11.x11_get_default_xdisplay())) self.group = None self.limits = {} self.background = None cursor = os.path.join(get_share_path(), "images", 'menu-cursor.svg') self.cursors = {} self.cursors[LEFT] = Gtk.Image.new_from_file(cursor) self.cursors[LEFT].set_name("osd-keyboard-cursor") self.cursors[RIGHT] = Gtk.Image.new_from_file(cursor) self.cursors[RIGHT].set_name("osd-keyboard-cursor") self.cursors[CPAD] = Gtk.Image.new_from_file(cursor) self.cursors[CPAD].set_name("osd-keyboard-cursor") self._eh_ids = [] self._controller = None self._stick = 0, 0 self._hovers = {self.cursors[LEFT]: None, self.cursors[RIGHT]: None} self._pressed = {self.cursors[LEFT]: None, self.cursors[RIGHT]: None} self._pressed_areas = {} self.c = Gtk.Box() self.c.set_name("osd-keyboard-container") self.f = Gtk.Fixed()
def __init__(self, gladepath="/usr/share/scc", imagepath="/usr/share/scc/images"): Gtk.Application.__init__(self, application_id="me.kozec.scc", flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE | Gio.ApplicationFlags.NON_UNIQUE ) UserDataManager.__init__(self) BindingEditor.__init__(self, self) # Setup Gtk.Application self.setup_commandline() # Setup DaemonManager self.dm = DaemonManager() self.dm.connect("alive", self.on_daemon_alive) self.dm.connect("controller-count-changed", self.on_daemon_ccunt_changed) self.dm.connect("dead", self.on_daemon_dead) self.dm.connect("error", self.on_daemon_error) self.dm.connect('reconfigured', self.on_daemon_reconfigured), self.dm.connect("version", self.on_daemon_version) # Set variables self.config = Config() self.gladepath = gladepath self.imagepath = imagepath self.builder = None self.recursing = False self.statusicon = None self.status = "unknown" self.context_menu_for = None self.daemon_changed_profile = False self.osd_mode = False # In OSD mode, only active profile can be editted self.osd_mode_mapper = None self.background = None self.outdated_version = None self.profile_switchers = [] self.current_file = None # Currently edited file self.controller_count = 0 self.current = Profile(GuiActionParser()) self.just_started = True self.button_widgets = {} self.hilights = { App.HILIGHT_COLOR : set(), App.OBSERVE_COLOR : set() } self.undo = [] self.redo = []
def __init__(self): svg = SVGEditor(file("images/binding-display.svg").read()) background = SVGEditor.get_element(svg, "background") self.label_template = SVGEditor.get_element(svg, "label_template") self.line_height = int(float(self.label_template.attrib.get("height") or 8)) self.char_width = int(float(self.label_template.attrib.get("width") or 8)) self.full_width = int(float(background.attrib.get("width") or 800)) self.full_height = int(float(background.attrib.get("height") or 800)) profile = Profile(TalkingActionParser()).load("test.sccprofile") boxes = [] box_bcs = Box(0, self.PADDING, Align.TOP, "bcs") box_bcs.add("BACK", Action.AC_BUTTON, profile.buttons.get(SCButtons.BACK)) box_bcs.add("C", Action.AC_BUTTON, profile.buttons.get(SCButtons.C)) box_bcs.add("START", Action.AC_BUTTON, profile.buttons.get(SCButtons.START)) boxes.append(box_bcs) box_left = Box(self.PADDING, self.PADDING, Align.LEFT | Align.TOP, "left", min_height = self.full_height * 0.5, min_width = self.full_width * 0.2) box_left.add("LEFT", Action.AC_TRIGGER, profile.triggers.get(profile.LEFT)) box_left.add("LB", Action.AC_BUTTON, profile.buttons.get(SCButtons.LB)) box_left.add("LGRIP", Action.AC_BUTTON, profile.buttons.get(SCButtons.LGRIP)) box_left.add("LPAD", Action.AC_PAD, profile.pads.get(profile.LEFT)) boxes.append(box_left) box_right = Box(self.PADDING, self.PADDING, Align.RIGHT | Align.TOP, "right", min_height = self.full_height * 0.5, min_width = self.full_width * 0.2) box_right.add("RIGHT", Action.AC_TRIGGER, profile.triggers.get(profile.RIGHT)) box_right.add("RB", Action.AC_BUTTON, profile.buttons.get(SCButtons.RB)) box_right.add("RGRIP", Action.AC_BUTTON, profile.buttons.get(SCButtons.RGRIP)) box_right.add("RPAD", Action.AC_PAD, profile.pads.get(profile.RIGHT)) boxes.append(box_right) box_abxy = Box(4 * self.PADDING, self.PADDING, Align.RIGHT | Align.BOTTOM, "abxy") box_abxy.add("A", Action.AC_BUTTON, profile.buttons.get(SCButtons.A)) box_abxy.add("B", Action.AC_BUTTON, profile.buttons.get(SCButtons.B)) box_abxy.add("X", Action.AC_BUTTON, profile.buttons.get(SCButtons.X)) box_abxy.add("Y", Action.AC_BUTTON, profile.buttons.get(SCButtons.Y)) boxes.append(box_abxy) box_stick = Box(4 * self.PADDING, self.PADDING, Align.LEFT | Align.BOTTOM, "stick") box_stick.add("STICK", Action.AC_STICK, profile.stick) boxes.append(box_stick) w = int(float(background.attrib.get("width") or 800)) h = int(float(background.attrib.get("height") or 800)) root = SVGEditor.get_element(svg, "root") for b in boxes: b.calculate(self) # Set ABXY and Stick size & position box_abxy.height = box_stick.height = self.full_height * 0.25 box_abxy.width = box_stick.width = self.full_width * 0.3 box_abxy.y = self.full_height - self.PADDING - box_abxy.height box_stick.y = self.full_height - self.PADDING - box_stick.height box_abxy.x = self.full_width - self.PADDING - box_abxy.width self.equal_width(box_left, box_right) self.equal_height(box_left, box_right) for b in boxes: b.place_marker(self, root) for b in boxes: b.place(self, root) file("out.svg", "w").write(svg.to_string())
def on_profile_changed(self, daemon, filename): profile = Profile(TalkingActionParser()).load(filename) Generator(SVGEditor(self.background), profile)