class EditorPage: """Filter editor GUI""" def __init__(self, filters, config): # Color page filters self.filters = filters # Filter edit helper self.filter_editor = RawFilterEditor(config.get("Editor", "preview")) # File dialog self.filechooser = FileChooser(acyls.dirs['filters'], "filter.xml") # Read icon size settins from config self.PREVIEW_ICON_SIZE = config.getint("PreviewSize", "single") # Load GUI self.builder = Gtk.Builder() self.builder.add_from_file( os.path.join(acyls.dirs['gui'], "editor.glade")) gui_elements = ( 'editor_grid', 'editor_textview', 'editor_preview_icon', 'filter_info_label', ) self.gui = { element: self.builder.get_object(element) for element in gui_elements } self.gui['editor_textview'].modify_font( Pango.FontDescription("Monospace")) # Build buffer self.buffer = Gtk.TextBuffer(text="Enter filter source here") self.gui['editor_textview'].set_buffer(self.buffer) # Mainpage buttnons hanlers self.mhandlers = dict() self.mhandlers['refresh_button'] = self.on_refresh_click # Toolbar buttnons hanlers self.bhandlers = dict() self.bhandlers[ 'edit_filter_toolbutton'] = self.on_edit_filter_button_click self.bhandlers[ 'load_filter_toolbutton'] = self.on_load_filter_button_click self.bhandlers[ 'revert_filter_toolbutton'] = self.on_revert_filter_button_click self.bhandlers[ 'save_filter_toolbutton'] = self.on_save_filter_button_click self.bhandlers[ 'save_as_filter_toolbutton'] = self.on_save_as_filter_button_click # Fill up GUI pixbuf = PixbufCreator.new_single_at_size(self.filter_editor.preview, self.PREVIEW_ICON_SIZE) self.gui['editor_preview_icon'].set_from_pixbuf(pixbuf) # Support functions def update_preview(self): """Update filter preview""" try: pixbuf = PixbufCreator.new_single_at_size( self.filter_editor.current_preview, self.PREVIEW_ICON_SIZE) self.gui['editor_preview_icon'].set_from_pixbuf(pixbuf) except Exception: self.gui['editor_preview_icon'].set_from_icon_name( 'image-missing', Gtk.IconSize.DIALOG) def set_filter_from_file(self, file_): """Load filter""" self.filter_editor.load_xml(file_) self.buffer.set_text(self.filter_editor.source) self.update_preview() self.gui['filter_info_label'].set_text( self.filter_editor.get_filter_info()) # GUI handlers def on_edit_filter_button_click(self, *args): self.set_filter_from_file(self.filters.current.fstore) def on_load_filter_button_click(self, *args): is_ok, file_ = self.filechooser.load() if is_ok: self.set_filter_from_file(file_) def on_save_filter_button_click(self, *args): self.filter_editor.save_xml() def on_save_as_filter_button_click(self, *args): is_ok, file_ = self.filechooser.save() if is_ok: self.filter_editor.save_xml(file_) self.gui['filter_info_label'].set_text( self.filter_editor.get_filter_info()) def on_revert_filter_button_click(self, *args): if self.filter_editor.xmlfile is not None: self.filter_editor.reset() self.buffer.set_text(self.filter_editor.source) self.update_preview() else: print("Error: filter was not saved") def on_refresh_click(self, *args): start, end = self.buffer.get_bounds() buffer_text = self.buffer.get_text(start, end, False) self.filter_editor.load_source(buffer_text) self.update_preview()
class ColorPage: """Colors tab""" def __init__(self, database, config): self.database = database self.config = config # Read icon size settins from config self.PREVIEW_ICON_SIZE = self.config.getint("PreviewSize", "single") # Load icon groups from config file self.icongroups = IconGroupCollector(self.config) # Build griadient object self.gradient = gradient.Gradient() # Load filters from certain directory self.filters = FilterCollector(acyls.dirs['filters']) self.filters.connect_signal(self.filter_refresh) # File dialog self.filechooser = FileChooser(acyls.dirs['user'], "custom.acyl") # Load GUI self.signals = dict() self.builder = Gtk.Builder() self.builder.add_from_file( os.path.join(acyls.dirs['gui'], "colors.glade")) gui_elements = ( 'colorbox', 'icongroup_combo', 'custom_icons_treeview', 'colorlist_treeview', 'gradient_combo', 'filter_group_combo', 'filters_combo', 'direction_treeview', 'handoffset_switch', 'filters_combo', 'colorlist_treeview_selection', 'offset_scale', 'color_selector', 'offset_scale', 'render_button', 'preview_icon', 'filter_settings_button', ) self.gui = { element: self.builder.get_object(element) for element in gui_elements } # Build stores self.build_data_stores() # Database setup self.build_data_hadlers() # Toolbar buttnons hanlers self.bhandlers = dict() self.bhandlers['add_color_toolbutton'] = self.on_add_color_button_click self.bhandlers[ 'remove_color_toolbutton'] = self.on_remove_color_button_click self.bhandlers[ 'copy_color_toolbutton'] = self.on_copy_settings_button_click self.bhandlers[ 'paste_color_toolbutton'] = self.on_paste_settings_button_click self.bhandlers[ 'save_settings_toolbutton'] = self.on_save_settings_button_click self.bhandlers[ 'load_settings_toolbutton'] = self.on_load_settings_button_click self.bhandlers[ 'reset_settings_toolbutton'] = self.on_reset_settings_button_click # Mainpage buttnons hanlers self.mhandlers = dict() self.mhandlers['refresh_button'] = self.on_refresh_click self.mhandlers['apply_button'] = self.on_apply_click # Init vars self.color_selected = None self.rtr = False self.init_confirmed = False self.state_buffer = {} # Fill up gui for name in self.icongroups.names: self.gui['icongroup_combo'].append_text(name) for tag in sorted(gradient.GRADIENT_PROFILES): self.gui['gradient_combo'].append_text(tag) for group in self.filters.groupnames: self.gui['filter_group_combo'].append_text(group) # connect signals self.connect_signals() self.gui['icongroup_combo'].set_active(0) # restore GUI elements state from last session self.gui['render_button'].set_active( self.config.getboolean("Settings", "autorender")) self.init_confirmed = True # Init functions def connect_signals(self): """Connect GUI handlers""" self.signals['colorlist'] = self.gui[ 'colorlist_treeview_selection'].connect( "changed", self.on_color_selection_changed) self.signals['handoffset_switch'] = self.gui[ 'handoffset_switch'].connect("notify::active", self.on_handoffset_toggled) self.signals['colorlist_del'] = self.store['colorlist'].connect( "row-deleted", self.on_colorlist_structure_changed) self.signals['colorlist_add'] = self.store['colorlist'].connect( "row-inserted", self.on_colorlist_structure_changed) self.signals['color_selector'] = self.gui['color_selector'].connect( "color_changed", self.on_color_change) self.gui['icongroup_combo'].connect("changed", self.on_icongroup_combo_changed) self.gui['filter_group_combo'].connect( "changed", self.on_filter_group_combo_changed) self.gui['filters_combo'].connect("changed", self.on_filter_combo_changed) self.gui['offset_scale'].connect("value_changed", self.on_offset_value_changed) self.gui['gradient_combo'].connect("changed", self.on_gradient_type_switched) self.gui['render_button'].connect("toggled", self.on_render_toggled) self.gui['filter_settings_button'].connect( "clicked", self.on_filter_settings_click) def build_data_stores(self): """Build stores for GUI dataviews""" self.store = dict() # custom icons self.ied = {'Name': 0, 'State': 1} self.store['custom_icons'] = Gtk.ListStore(str, bool) self.store['custom_icons'].append(["Simple Icon Group", False]) renderer_toggle = Gtk.CellRendererToggle() renderer_toggle.connect("toggled", self.on_custom_icon_toggled) self.gui['custom_icons_treeview'].append_column( Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=0)) self.gui['custom_icons_treeview'].append_column( Gtk.TreeViewColumn("State", renderer_toggle, active=1)) self.gui['custom_icons_treeview'].set_model(self.store['custom_icons']) # color list self.ced = {'Color': 0, 'Alpha': 1, 'Offset': 2, 'RGBA': 3} colorstore_visible_keys = [k for k in self.ced.keys() if k != 'RGBA'] self.store['colorlist'] = Gtk.ListStore(str, float, int, str) for key in sorted(colorstore_visible_keys, key=lambda k: self.ced[k]): self.gui['colorlist_treeview'].append_column( Gtk.TreeViewColumn(key, Gtk.CellRendererText(), text=self.ced[key])) self.gui['colorlist_treeview'].set_model(self.store['colorlist']) # gradient direction self.ded = {'Coord': 0, 'Value': 1} self.store['direction'] = Gtk.ListStore(str, int) self.gui['renderer_spin'] = Gtk.CellRendererSpin( editable=True, adjustment=Gtk.Adjustment(0, 0, 100, 5, 0, 0)) self.signals['direction_edited'] = self.gui['renderer_spin'].connect( "edited", self.on_direction_edited) self.gui['direction_treeview'].append_column( Gtk.TreeViewColumn("Coord", Gtk.CellRendererText(), text=0)) self.gui['direction_treeview'].append_column( Gtk.TreeViewColumn("Value", self.gui['renderer_spin'], text=1)) self.gui['direction_treeview'].set_model(self.store['direction']) def build_data_hadlers(self): """GUI state from/to database""" # Read GUI setting from database def read_colors(dump): # Fix this with self.gui['colorlist_treeview_selection'].handler_block( self.signals['colorlist']): with self.store['colorlist'].handler_block( self.signals['colorlist_add']): with self.store['colorlist'].handler_block( self.signals['colorlist_del']): self.store['colorlist'].clear() for color in dump['colors']: self.store['colorlist'].append(color) with self.gui['color_selector'].handler_block( self.signals['color_selector']): self.on_colorlist_structure_changed() def read_gradient_type(dump): self.gui['gradient_combo'].set_active( gradient.GRADIENT_PROFILES[dump['gradtype']]['index']) def read_filter_name(dump): filter_ = dump['filter'] self.gui['filter_group_combo'].set_active( self.filters.get_group_index(filter_)) filter_index = self.filters.names.index( filter_) if filter_ in self.filters.names else 0 self.gui['filters_combo'].set_active(filter_index) def read_gradient_settings(dump): with self.gui['renderer_spin'].handler_block( self.signals['direction_edited']): self.store['direction'].clear() for coord in dump[self.gradient.tag]: self.store['direction'].append(coord) def read_autoofset_settings(dump): with self.gui['handoffset_switch'].handler_block( self.signals['handoffset_switch']): self.gui['handoffset_switch'].set_active( not dump['autooffset']) self.gui['offset_scale'].set_sensitive(not dump['autooffset']) self.data_read_handler = { 'colors': read_colors, 'linearGradient': read_gradient_settings, 'radialGradient': read_gradient_settings, 'autooffset': read_autoofset_settings, 'gradtype': read_gradient_type, 'filter': read_filter_name, } # Write GUI setting to database def write_colors(dump): dump['colors'] = [list(row) for row in self.store['colorlist']] def write_gradient_type(dump): dump['gradtype'] = self.gradient.tag def write_autoofset_settings(dump): dump['autooffset'] = not self.gui['handoffset_switch'].get_active() def write_filter_name(dump): dump['filter'] = self.gui['filters_combo'].get_active_text() def write_gradient_settings(dump): dump[self.gradient.tag] = [ list(row) for row in self.store['direction'] ] self.data_write_handler = { 'gradtype': write_gradient_type, 'autooffset': write_autoofset_settings, 'filter': write_filter_name, 'colors': write_colors, 'linearGradient': write_gradient_settings, 'radialGradient': write_gradient_settings, } # Support functions def read_gui_setting_from_base(self, keys=None): """Read settings from file and set GUI according it""" keys = keys if keys is not None else self.get_current_base_keys() dump = self.database.get_dump(self.icongroups.current.name) for key in keys: self.data_read_handler[key](dump) self.update() def write_gui_settings_to_base(self, keys=None): """Write settings to file""" keys = keys if keys is not None else self.get_current_base_keys() dump = self.database.get_dump(self.icongroups.current.name) for key in keys: self.data_write_handler[key](dump) def get_current_base_keys(self): """Get current keys for databse access""" keys = ['filter', 'gradtype', 'autooffset', 'colors'] keys.append(self.gradient.tag) return keys def set_offset_auto(self): """Set fair offset for all colors in gradient""" rownum = len(self.store['colorlist']) if rownum > 1: step = 100 / (rownum - 1) for i, row in enumerate(self.store['colorlist']): row[self.ced['Offset']] = i * step elif rownum == 1: self.store['colorlist'][0][self.ced['Offset']] = 100 def current_state(self): """Get current icon settings""" return dict(gradient=self.gradient, gfilter=self.filters.current, data=self.database.get_dump(self.icongroups.current.name)) def filter_refresh(self, caller, forced): """Filter update handler""" self.refresh(forced) def refresh(self, forced=False): """Full update for GUI state""" if self.rtr or forced: self.write_gui_settings_to_base() self.update() def update(self): """Refresh icon preview""" state = self.current_state() self.icongroups.current.preview = iconchanger.rebuild_text( self.icongroups.current.preview, **state) pixbuf = self.icongroups.current.get_preview_pixbuf( self.PREVIEW_ICON_SIZE) self.gui['preview_icon'].set_from_pixbuf(pixbuf) # GUI handlers def on_refresh_click(self, *args): self.write_gui_settings_to_base() self.update() def on_gradient_type_switched(self, combo): if self.init_confirmed: # fix this: first switch self.write_gui_settings_to_base([self.gradient.tag]) self.gradient.set_tag(combo.get_active_text()) self.write_gui_settings_to_base(['gradtype']) self.read_gui_setting_from_base(['gradtype', self.gradient.tag]) def on_direction_edited(self, widget, path, text): self.store['direction'][path][self.ded['Value']] = int(text) self.refresh() def on_custom_icon_toggled(self, widget, path): self.store['custom_icons'][path][self.ied[ 'State']] = not self.store['custom_icons'][path][self.ied['State']] name = self.store['custom_icons'][path][self.ied['Name']].lower() self.icongroups.current.switch_state(name) self.refresh(forced=True) def on_offset_value_changed(self, scale): offset = scale.get_value() if self.color_selected is not None: self.store['colorlist'].set_value(self.color_selected, self.ced['Offset'], int(offset)) self.refresh() def on_filter_group_combo_changed(self, combo): group = combo.get_active_text() self.filters.set_group(group) self.gui['filters_combo'].remove_all() for name in self.filters.names: self.gui['filters_combo'].append_text(name) self.gui['filters_combo'].set_active(0) def on_filter_combo_changed(self, combo): name = combo.get_active_text() if name is not None: self.filters.switch(name) self.gui['filter_settings_button'].set_sensitive( self.filters.current.is_custom) self.write_gui_settings_to_base(['filter']) self.update() def on_colorlist_structure_changed(self, *args): if self.database.get_key(self.icongroups.current.name, 'autooffset'): self.set_offset_auto() if len(self.store['colorlist']) > 0: last = len(self.store['colorlist']) - 1 self.gui['colorlist_treeview'].set_cursor(last) self.gui['offset_scale'].set_value( self.store['colorlist'][last][self.ced['Offset']]) def on_color_selection_changed(self, selection): model, sel = selection.get_selected() if sel is not None: self.color_selected = sel rgba = Gdk.RGBA() rgba.parse(model[sel][self.ced['RGBA']]) rgba.alpha = model[sel][self.ced['Alpha']] self.gui['color_selector'].set_current_rgba(rgba) offset = model[sel][self.ced['Offset']] self.gui['offset_scale'].set_value(offset) def on_handoffset_toggled(self, switch, *args): is_active = switch.get_active() self.gui['offset_scale'].set_sensitive(is_active) self.write_gui_settings_to_base(['autooffset']) if self.database.get_key(self.icongroups.current.name, 'autooffset'): self.set_offset_auto() self.gui['offset_scale'].set_value( self.store['colorlist'][self.color_selected][self.ced['Offset']]) self.refresh() def on_icongroup_combo_changed(self, combo): if self.init_confirmed: # fix this: first switch self.write_gui_settings_to_base() files = self.icongroups.current.get_test() iconchanger.rebuild(*files, **self.current_state()) self.icongroups.switch(combo.get_active_text()) if self.icongroups.current.is_custom: self.store['custom_icons'].clear() for key, value in self.icongroups.current.state.items(): self.store['custom_icons'].append([key.capitalize(), value]) self.gui['custom_icons_treeview'].set_sensitive( self.icongroups.current.is_custom) self.read_gui_setting_from_base() def on_color_change(self, *args): rgba = self.gui['color_selector'].get_current_rgba() self.store['colorlist'].set_value(self.color_selected, self.ced['Color'], hex_from_rgba(rgba)) self.store['colorlist'].set_value(self.color_selected, self.ced['Alpha'], rgba.alpha) self.store['colorlist'].set_value(self.color_selected, self.ced['RGBA'], rgba.to_string()) self.refresh() def on_render_toggled(self, switch, *args): self.rtr = switch.get_active() self.config.set("Settings", "autorender", str(self.rtr)) self.refresh() # Toolbar buttons handlers def on_add_color_button_click(self, *args): rgba = self.gui['color_selector'].get_current_rgba() hexcolor = hex_from_rgba(rgba) self.store['colorlist'].append( [hexcolor, rgba.alpha, 100, rgba.to_string()]) def on_remove_color_button_click(self, *args): if len(self.store['colorlist']) > 1: self.store['colorlist'].remove(self.color_selected) def on_copy_settings_button_click(self, *args): self.state_buffer = deepcopy( self.database.get_dump(self.icongroups.current.name)) def on_paste_settings_button_click(self, *args): self.database.update(self.icongroups.current.name, self.state_buffer) self.read_gui_setting_from_base() def on_save_settings_button_click(self, *args): is_ok, file_ = self.filechooser.save() if is_ok: self.database.save_to_file(file_) def on_load_settings_button_click(self, *args): is_ok, file_ = self.filechooser.load() if is_ok: self.database.load_from_file(file_) self.read_gui_setting_from_base() def on_reset_settings_button_click(self, *args): self.database.reset(self.icongroups.current.name) self.read_gui_setting_from_base() def on_filter_settings_click(self, widget, data=None): self.filters.current.gui['window'].show_all() @multithread def on_apply_click(self, *args): files = self.icongroups.current.get_real() iconchanger.rebuild(*files, **self.current_state()) def on_page_switch(self): self.gui['render_button'].emit("toggled")
class ColorPage: """Colors tab""" def __init__(self, database, config): self.database = database self.config = config # Read icon size settins from config self.PREVIEW_ICON_SIZE = int(self.config.get("PreviewSize", "single")) # Load icon groups from config file self.icongroups = IconGroupCollector(self.config) # Build griadient object self.gradient = gradient.Gradient() # Load filters from certain directory self.filters = FilterCollector(acyls.dirs['filters']) self.filters.connect_signal(self.filter_refresh) # File dialog self.filechooser = FileChooser(acyls.dirs['user'], "custom.acyl") # Load GUI self.signals = dict() self.builder = Gtk.Builder() self.builder.add_from_file(os.path.join(acyls.dirs['gui'], "colors.glade")) gui_elements = ( 'colorbox', 'icongroup_combo', 'custom_icons_treeview', 'colorlist_treeview', 'gradient_combo', 'filter_group_combo', 'filters_combo', 'direction_treeview', 'handoffset_switch', 'filters_combo', 'colorlist_treeview_selection', 'offset_scale', 'color_selector', 'offset_scale', 'render_button', 'preview_icon', 'filter_settings_button', ) self.gui = {element: self.builder.get_object(element) for element in gui_elements} # Build stores self.build_data_stores() # Database setup self.build_data_hadlers() # Toolbar buttnons hanlers self.bhandlers = dict() self.bhandlers['add_color_toolbutton'] = self.on_add_color_button_click self.bhandlers['remove_color_toolbutton'] = self.on_remove_color_button_click self.bhandlers['copy_color_toolbutton'] = self.on_copy_settings_button_click self.bhandlers['paste_color_toolbutton'] = self.on_paste_settings_button_click self.bhandlers['save_settings_toolbutton'] = self.on_save_settings_button_click self.bhandlers['load_settings_toolbutton'] = self.on_load_settings_button_click self.bhandlers['reset_settings_toolbutton'] = self.on_reset_settings_button_click # Mainpage buttnons hanlers self.mhandlers = dict() self.mhandlers['refresh_button'] = self.on_refresh_click self.mhandlers['apply_button'] = self.on_apply_click # Init vars self.color_selected = None self.rtr = False self.init_confirmed = False self.state_buffer = {} # Fill up gui for name in self.icongroups.names: self.gui['icongroup_combo'].append_text(name) for tag in sorted(gradient.GRADIENT_PROFILES): self.gui['gradient_combo'].append_text(tag) for group in self.filters.groupnames: self.gui['filter_group_combo'].append_text(group) # connect signals self.connect_signals() self.gui['icongroup_combo'].set_active(0) # restore GUI elements state from last session self.gui['render_button'].set_active(self.config.getboolean("Settings", "autorender")) self.init_confirmed = True # Init functions def connect_signals(self): """Connect GUI handlers""" self.signals['colorlist'] = self.gui['colorlist_treeview_selection'].connect( "changed", self.on_color_selection_changed ) self.signals['handoffset_switch'] = self.gui['handoffset_switch'].connect( "notify::active", self.on_handoffset_toggled ) self.signals['colorlist_del'] = self.store['colorlist'].connect( "row-deleted", self.on_colorlist_structure_changed ) self.signals['colorlist_add'] = self.store['colorlist'].connect( "row-inserted", self.on_colorlist_structure_changed ) self.signals['color_selector'] = self.gui['color_selector'].connect( "color_changed", self.on_color_change ) self.gui['icongroup_combo'].connect("changed", self.on_icongroup_combo_changed) self.gui['filter_group_combo'].connect("changed", self.on_filter_group_combo_changed) self.gui['filters_combo'].connect("changed", self.on_filter_combo_changed) self.gui['offset_scale'].connect("value_changed", self.on_offset_value_changed) self.gui['gradient_combo'].connect("changed", self.on_gradient_type_switched) self.gui['render_button'].connect("toggled", self.on_render_toggled) self.gui['filter_settings_button'].connect("clicked", self.on_filter_settings_click) def build_data_stores(self): """Build stores for GUI dataviews""" self.store = dict() # custom icons self.ied = {'Name': 0, 'State': 1} self.store['custom_icons'] = Gtk.ListStore(str, bool) self.store['custom_icons'].append(["Simple Icon Group", False]) renderer_toggle = Gtk.CellRendererToggle() renderer_toggle.connect("toggled", self.on_custom_icon_toggled) self.gui['custom_icons_treeview'].append_column(Gtk.TreeViewColumn("Name", Gtk.CellRendererText(), text=0)) self.gui['custom_icons_treeview'].append_column(Gtk.TreeViewColumn("State", renderer_toggle, active=1)) self.gui['custom_icons_treeview'].set_model(self.store['custom_icons']) # color list self.ced = {'Color': 0, 'Alpha': 1, 'Offset': 2, 'RGBA': 3} colorstore_visible_keys = [k for k in self.ced.keys() if k != 'RGBA'] self.store['colorlist'] = Gtk.ListStore(str, float, int, str) for key in sorted(colorstore_visible_keys, key=lambda k: self.ced[k]): self.gui['colorlist_treeview'].append_column( Gtk.TreeViewColumn(key, Gtk.CellRendererText(), text=self.ced[key]) ) self.gui['colorlist_treeview'].set_model(self.store['colorlist']) # gradient direction self.ded = {'Coord': 0, 'Value': 1} self.store['direction'] = Gtk.ListStore(str, int) self.gui['renderer_spin'] = Gtk.CellRendererSpin(editable=True, adjustment=Gtk.Adjustment(0, 0, 100, 5, 0, 0)) self.signals['direction_edited'] = self.gui['renderer_spin'].connect("edited", self.on_direction_edited) self.gui['direction_treeview'].append_column(Gtk.TreeViewColumn("Coord", Gtk.CellRendererText(), text=0)) self.gui['direction_treeview'].append_column(Gtk.TreeViewColumn("Value", self.gui['renderer_spin'], text=1)) self.gui['direction_treeview'].set_model(self.store['direction']) def build_data_hadlers(self): """GUI state from/to database""" # Read GUI setting from database def read_colors(dump): # Fix this with self.gui['colorlist_treeview_selection'].handler_block(self.signals['colorlist']): with self.store['colorlist'].handler_block(self.signals['colorlist_add']): with self.store['colorlist'].handler_block(self.signals['colorlist_del']): self.store['colorlist'].clear() for color in dump['colors']: self.store['colorlist'].append(color) with self.gui['color_selector'].handler_block(self.signals['color_selector']): self.on_colorlist_structure_changed() def read_gradient_type(dump): self.gui['gradient_combo'].set_active(gradient.GRADIENT_PROFILES[dump['gradtype']]['index']) def read_filter_name(dump): filter_ = dump['filter'] self.gui['filter_group_combo'].set_active(self.filters.get_group_index(filter_)) filter_index = self.filters.names.index(filter_) if filter_ in self.filters.names else 0 self.gui['filters_combo'].set_active(filter_index) def read_gradient_settings(dump): with self.gui['renderer_spin'].handler_block(self.signals['direction_edited']): self.store['direction'].clear() for coord in dump[self.gradient.tag]: self.store['direction'].append(coord) def read_autoofset_settings(dump): with self.gui['handoffset_switch'].handler_block(self.signals['handoffset_switch']): self.gui['handoffset_switch'].set_active(not dump['autooffset']) self.gui['offset_scale'].set_sensitive(not dump['autooffset']) self.data_read_handler = { 'colors': read_colors, 'linearGradient': read_gradient_settings, 'radialGradient': read_gradient_settings, 'autooffset': read_autoofset_settings, 'gradtype': read_gradient_type, 'filter': read_filter_name, } # Write GUI setting to database def write_colors(dump): dump['colors'] = [list(row) for row in self.store['colorlist']] def write_gradient_type(dump): dump['gradtype'] = self.gradient.tag def write_autoofset_settings(dump): dump['autooffset'] = not self.gui['handoffset_switch'].get_active() def write_filter_name(dump): dump['filter'] = self.gui['filters_combo'].get_active_text() def write_gradient_settings(dump): dump[self.gradient.tag] = [list(row) for row in self.store['direction']] self.data_write_handler = { 'gradtype': write_gradient_type, 'autooffset': write_autoofset_settings, 'filter': write_filter_name, 'colors': write_colors, 'linearGradient': write_gradient_settings, 'radialGradient': write_gradient_settings, } # Support functions def read_gui_setting_from_base(self, keys=None): """Read settings from file and set GUI according it""" keys = keys if keys is not None else self.get_current_base_keys() dump = self.database.get_dump(self.icongroups.current.name) for key in keys: self.data_read_handler[key](dump) self.update() def write_gui_settings_to_base(self, keys=None): """Write settings to file""" keys = keys if keys is not None else self.get_current_base_keys() dump = self.database.get_dump(self.icongroups.current.name) for key in keys: self.data_write_handler[key](dump) def get_current_base_keys(self): """Get current keys for databse access""" keys = ['filter', 'gradtype', 'autooffset', 'colors'] keys.append(self.gradient.tag) return keys def set_offset_auto(self): """Set fair offset for all colors in gradient""" rownum = len(self.store['colorlist']) if rownum > 1: step = 100 / (rownum - 1) for i, row in enumerate(self.store['colorlist']): row[self.ced['Offset']] = i * step elif rownum == 1: self.store['colorlist'][0][self.ced['Offset']] = 100 def current_state(self): """Get current icon settings""" return dict( gradient = self.gradient, gfilter = self.filters.current, data = self.database.get_dump(self.icongroups.current.name) ) def filter_refresh(self, caller, forced): """Filter update handler""" self.refresh(forced) def refresh(self, forced=False): """Full update for GUI state""" if self.rtr or forced: self.write_gui_settings_to_base() self.update() def update(self): """Refresh icon preview""" state = self.current_state() self.icongroups.current.preview = iconchanger.rebuild_text(self.icongroups.current.preview, **state) pixbuf = self.icongroups.current.get_preview_pixbuf(self.PREVIEW_ICON_SIZE) self.gui['preview_icon'].set_from_pixbuf(pixbuf) # GUI handlers def on_refresh_click(self, *args): self.write_gui_settings_to_base() self.update() def on_gradient_type_switched(self, combo): if self.init_confirmed: # fix this: first switch self.write_gui_settings_to_base([self.gradient.tag]) self.gradient.set_tag(combo.get_active_text()) self.write_gui_settings_to_base(['gradtype']) self.read_gui_setting_from_base(['gradtype', self.gradient.tag]) def on_direction_edited(self, widget, path, text): self.store['direction'][path][self.ded['Value']] = int(text) self.refresh() def on_custom_icon_toggled(self, widget, path): self.store['custom_icons'][path][self.ied['State']] = not self.store['custom_icons'][path][self.ied['State']] name = self.store['custom_icons'][path][self.ied['Name']].lower() self.icongroups.current.switch_state(name) self.refresh(forced=True) def on_offset_value_changed(self, scale): offset = scale.get_value() if self.color_selected is not None: self.store['colorlist'].set_value(self.color_selected, self.ced['Offset'], int(offset)) self.refresh() def on_filter_group_combo_changed(self, combo): group = combo.get_active_text() self.filters.set_group(group) self.gui['filters_combo'].remove_all() for name in self.filters.names: self.gui['filters_combo'].append_text(name) self.gui['filters_combo'].set_active(0) def on_filter_combo_changed(self, combo): name = combo.get_active_text() if name is not None: self.filters.switch(name) self.gui['filter_settings_button'].set_sensitive(self.filters.current.is_custom) self.write_gui_settings_to_base(['filter']) self.update() def on_colorlist_structure_changed(self, *args): if self.database.get_key(self.icongroups.current.name, 'autooffset'): self.set_offset_auto() if len(self.store['colorlist']) > 0: last = len(self.store['colorlist']) - 1 self.gui['colorlist_treeview'].set_cursor(last) self.gui['offset_scale'].set_value(self.store['colorlist'][last][self.ced['Offset']]) def on_color_selection_changed(self, selection): model, sel = selection.get_selected() if sel is not None: self.color_selected = sel rgba = Gdk.RGBA() rgba.parse(model[sel][self.ced['RGBA']]) rgba.alpha = model[sel][self.ced['Alpha']] self.gui['color_selector'].set_current_rgba(rgba) offset = model[sel][self.ced['Offset']] self.gui['offset_scale'].set_value(offset) def on_handoffset_toggled(self, switch, *args): is_active = switch.get_active() self.gui['offset_scale'].set_sensitive(is_active) self.write_gui_settings_to_base(['autooffset']) if self.database.get_key(self.icongroups.current.name, 'autooffset'): self.set_offset_auto() self.gui['offset_scale'].set_value(self.store['colorlist'][self.color_selected][self.ced['Offset']]) self.refresh() def on_icongroup_combo_changed(self, combo): if self.init_confirmed: # fix this: first switch self.write_gui_settings_to_base() files = self.icongroups.current.get_test() iconchanger.rebuild(*files, **self.current_state()) self.icongroups.switch(combo.get_active_text()) if self.icongroups.current.is_custom: self.store['custom_icons'].clear() for key, value in self.icongroups.current.state.items(): self.store['custom_icons'].append([key.capitalize(), value]) self.gui['custom_icons_treeview'].set_sensitive(self.icongroups.current.is_custom) self.read_gui_setting_from_base() def on_color_change(self, *args): rgba = self.gui['color_selector'].get_current_rgba() self.store['colorlist'].set_value(self.color_selected, self.ced['Color'], hex_from_rgba(rgba)) self.store['colorlist'].set_value(self.color_selected, self.ced['Alpha'], rgba.alpha) self.store['colorlist'].set_value(self.color_selected, self.ced['RGBA'], rgba.to_string()) self.refresh() def on_render_toggled(self, switch, *args): self.rtr = switch.get_active() self.config.set("Settings", "autorender", str(self.rtr)) self.refresh() # Toolbar buttons handlers def on_add_color_button_click(self, *args): rgba = self.gui['color_selector'].get_current_rgba() hexcolor = hex_from_rgba(rgba) self.store['colorlist'].append([hexcolor, rgba.alpha, 100, rgba.to_string()]) def on_remove_color_button_click(self, *args): if len(self.store['colorlist']) > 1: self.store['colorlist'].remove(self.color_selected) def on_copy_settings_button_click(self, *args): self.state_buffer = deepcopy(self.database.get_dump(self.icongroups.current.name)) def on_paste_settings_button_click(self, *args): self.database.update(self.icongroups.current.name, self.state_buffer) self.read_gui_setting_from_base() def on_save_settings_button_click(self, *args): is_ok, file_ = self.filechooser.save() if is_ok: self.database.save_to_file(file_) def on_load_settings_button_click(self, *args): is_ok, file_ = self.filechooser.load() if is_ok: self.database.load_from_file(file_) self.read_gui_setting_from_base() def on_reset_settings_button_click(self, *args): self.database.reset(self.icongroups.current.name) self.read_gui_setting_from_base() def on_filter_settings_click(self, widget, data=None): self.filters.current.gui['window'].show_all() @multithread def on_apply_click(self, *args): files = self.icongroups.current.get_real() iconchanger.rebuild(*files, **self.current_state()) def on_page_switch(self): self.gui['render_button'].emit("toggled")
class EditorPage: """Filter editor GUI""" def __init__(self, filters, config): # Color page filters self.filters = filters # Filter edit helper self.filter_editor = RawFilterEditor(config.get("Editor", "preview")) # File dialog self.filechooser = FileChooser(acyls.dirs['filters'], "filter.xml") # Read icon size settins from config self.PREVIEW_ICON_SIZE = int(config.get("PreviewSize", "single")) # Load GUI self.builder = Gtk.Builder() self.builder.add_from_file(os.path.join(acyls.dirs['gui'], "editor.glade")) gui_elements = ( 'editor_grid', 'editor_textview', 'editor_preview_icon', 'filter_info_label', ) self.gui = {element: self.builder.get_object(element) for element in gui_elements} self.gui['editor_textview'].modify_font(Pango.FontDescription("Monospace")) # Build buffer self.buffer = Gtk.TextBuffer(text="Enter filter source here") self.gui['editor_textview'].set_buffer(self.buffer) # Mainpage buttnons hanlers self.mhandlers = dict() self.mhandlers['refresh_button'] = self.on_refresh_click # Toolbar buttnons hanlers self.bhandlers = dict() self.bhandlers['edit_filter_toolbutton'] = self.on_edit_filter_button_click self.bhandlers['load_filter_toolbutton'] = self.on_load_filter_button_click self.bhandlers['revert_filter_toolbutton'] = self.on_revert_filter_button_click self.bhandlers['save_filter_toolbutton'] = self.on_save_filter_button_click self.bhandlers['save_as_filter_toolbutton'] = self.on_save_as_filter_button_click # Fill up GUI pixbuf = PixbufCreator.new_single_at_size(self.filter_editor.preview, self.PREVIEW_ICON_SIZE) self.gui['editor_preview_icon'].set_from_pixbuf(pixbuf) # Support functions def update_preview(self): """Update filter preview""" try: pixbuf = PixbufCreator.new_single_at_size(self.filter_editor.current_preview, self.PREVIEW_ICON_SIZE) self.gui['editor_preview_icon'].set_from_pixbuf(pixbuf) except Exception: self.gui['editor_preview_icon'].set_from_icon_name('image-missing', Gtk.IconSize.DIALOG) def set_filter_from_file(self, file_): """Load filter""" self.filter_editor.load_xml(file_) self.buffer.set_text(self.filter_editor.source) self.update_preview() self.gui['filter_info_label'].set_text(self.filter_editor.get_filter_info()) # GUI handlers def on_edit_filter_button_click(self, *args): self.set_filter_from_file(self.filters.current.fstore) def on_load_filter_button_click(self, *args): is_ok, file_ = self.filechooser.load() if is_ok: self.set_filter_from_file(file_) def on_save_filter_button_click(self, *args): self.filter_editor.save_xml() def on_save_as_filter_button_click(self, *args): is_ok, file_ = self.filechooser.save() if is_ok: self.filter_editor.save_xml(file_) self.gui['filter_info_label'].set_text(self.filter_editor.get_filter_info()) def on_revert_filter_button_click(self, *args): if self.filter_editor.xmlfile is not None: self.filter_editor.reset() self.buffer.set_text(self.filter_editor.source) self.update_preview() else: print("Error: filter was not saved") def on_refresh_click(self, *args): start, end = self.buffer.get_bounds() buffer_text = self.buffer.get_text(start, end, False) self.filter_editor.load_source(buffer_text) self.update_preview()