def update(self, doc=None): self.data = self.ani.timeline self.data.cleanup() current_layer = self.doc.ani.timeline.layer # Update the common widgets self.opacity_scale.set_value(current_layer.opacity * 100) self.update_opacity_tooltip() combo = self.layer_mode_combo already_correct = (combo.get_active_id() == str( current_layer.composite)) if not already_correct: combo.set_active_id(str(current_layer.composite)) label, desc = COMBINE_MODE_STRINGS.get(current_layer.composite) tooltip = self.tooltip_format.format( blendingmode_name=escape(label), blendingmode_description=escape(desc)) combo.set_tooltip_markup(tooltip) self._update_buttons_sensitive() if self.ani.cleared == True: self.ani.cleared = False self.update_digits() self.timeline_widget.resize() self.scroll_to(self.ani.timeline.idx) self.emit('update') if not self.is_playing and self.ani.player_state == "play": use_lightbox = self.app.preferences.get("xsheet.play_lightbox", False) self._play_animation(use_lightbox=use_lightbox)
def __init__(self): """Initialize, called by the LayerMode FactoryAction making a menu""" Gtk.ImageMenuItem.__init__(self) menu = Gtk.Menu() self._menu_items = [] prev_item = None for mode in range(NUM_COMBINE_MODES): label, tooltip = COMBINE_MODE_STRINGS.get(mode) if prev_item is None: item = Gtk.RadioMenuItem() else: item = Gtk.RadioMenuItem(group=prev_item) item.set_label(label) item.set_tooltip_text(tooltip) item.connect("activate", self._item_activated_cb, mode) menu.append(item) self._menu_items.append((mode, item)) prev_item = item self._submenu = menu self.set_submenu(self._submenu) self._submenu.show_all() from application import get_app app = get_app() self._model = app.doc.model rootstack = self._model.layer_stack rootstack.layer_properties_changed += self._update_actions rootstack.current_path_updated += self._update_actions self._updating = False self._update_actions()
def update(self, doc=None): self.data = self.ani.timeline self.data.cleanup() current_layer = self.doc.ani.timeline.layer # Update the common widgets self.opacity_scale.set_value(current_layer.opacity*100) self.update_opacity_tooltip() combo = self.layer_mode_combo already_correct = (combo.get_active_id() == str(current_layer.composite)) if not already_correct: combo.set_active_id(str(current_layer.composite)) label, desc = COMBINE_MODE_STRINGS.get(current_layer.composite) tooltip = self.tooltip_format.format( blendingmode_name = escape(label), blendingmode_description = escape(desc)) combo.set_tooltip_markup(tooltip) self._update_buttons_sensitive() if self.ani.cleared == True: self.ani.cleared = False self.update_digits() self.timeline_widget.resize() self.scroll_to(self.ani.timeline.idx) self.emit('update') if not self.is_playing and self.ani.player_state == "play": use_lightbox = self.app.preferences.get("xsheet.play_lightbox", False) self._play_animation(use_lightbox=use_lightbox)
def on_layer_mode_changed(self, *ignored): doc = self.app.doc.model mode = int(self.layer_mode_combo.get_active_id()) label, desc = COMBINE_MODE_STRINGS.get(mode) doc.ani.set_layer_composite(mode) tooltip = self.tooltip_format.format( blendingmode_name=escape(label), blendingmode_description=escape(desc)) self.layer_mode_combo.set_tooltip_markup(tooltip)
def on_layer_mode_changed(self, *ignored): doc = self.app.doc.model mode = int(self.layer_mode_combo.get_active_id()) label, desc = COMBINE_MODE_STRINGS.get(mode) doc.ani.set_layer_composite(mode) tooltip = self.tooltip_format.format( blendingmode_name = escape(label), blendingmode_description = escape(desc)) self.layer_mode_combo.set_tooltip_markup(tooltip)
def _layer_mode_combo_changed_cb(self, *ignored): """Propagate the user's choice of layer mode to the model""" if self._processing_model_updates: return docmodel = self.app.doc.model combo = self._layer_mode_combo mode = int(combo.get_active_id()) if docmodel.layer_stack.current.mode == mode: return label, desc = COMBINE_MODE_STRINGS.get(mode) docmodel.set_current_layer_mode(mode)
def _update_layer_mode_combo(self): """Updates the layer mode combo's value from the model""" assert self._processing_model_updates combo = self._layer_mode_combo layer = self.app.doc.model.layer_stack.current if combo.get_active_id() == str(layer.mode): return combo.set_active_id(str(layer.mode)) label, desc = COMBINE_MODE_STRINGS.get(layer.mode) template = self.LAYER_MODE_TOOLTIP_MARKUP_TEMPLATE tooltip = template.format(name=escape(label), description=escape(desc)) combo.set_tooltip_markup(tooltip)
def _update_layer_mode_combo(self): """Updates the layer mode combo's value from the model""" assert self._processing_model_updates combo = self._layer_mode_combo rootstack = self.app.doc.model.layer_stack layer = rootstack.current if layer is rootstack or not layer: combo.set_sensitive(False) return elif not combo.get_sensitive(): combo.set_sensitive(True) already_correct = (combo.get_active_id() == str(layer.mode)) if already_correct: return combo.set_active_id(str(layer.mode)) label, desc = COMBINE_MODE_STRINGS.get(layer.mode) template = self.LAYER_MODE_TOOLTIP_MARKUP_TEMPLATE tooltip = template.format(name=escape(label), description=escape(desc)) combo.set_tooltip_markup(tooltip)
def _update_layer_mode_combo(self): """Updates the layer mode combo's value from the model""" assert self._processing_model_updates combo = self._layer_mode_combo rootstack = self.app.doc.model.layer_stack layer = rootstack.current if layer is rootstack or not layer: combo.set_sensitive(False) return elif not combo.get_sensitive(): combo.set_sensitive(True) already_correct = (combo.get_active_id() == str(layer.mode)) if already_correct: return combo.set_active_id(str(layer.mode)) label, desc = COMBINE_MODE_STRINGS.get(layer.mode) template = self.LAYER_MODE_TOOLTIP_MARKUP_TEMPLATE tooltip = template.format( name=escape(label), description=escape(desc) ) combo.set_tooltip_markup(tooltip)
def __init__(self): GObject.GObject.__init__(self) from application import get_app app = get_app() self.app = app self.set_spacing(widgets.SPACING_CRAMPED) self.set_border_width(widgets.SPACING_TIGHT) # GtkTreeView init docmodel = app.doc.model view = Gtk.TreeView() treemodel = layers.RootStackTreeModelWrapper(docmodel) view.set_model(treemodel) self._treemodel = treemodel view.set_reorderable(True) view.set_headers_visible(False) view.connect("button-press-event", self._view_button_press_cb) self._treeview = view # View behaviour and appearance sel = view.get_selection() sel.set_mode(Gtk.SelectionMode.SINGLE) view_scroll = Gtk.ScrolledWindow() view_scroll.set_shadow_type(Gtk.ShadowType.ETCHED_IN) scroll_pol = Gtk.PolicyType.AUTOMATIC view_scroll.set_policy(scroll_pol, scroll_pol) view_scroll.add(view) view_scroll.set_size_request(-1, 100) view_scroll.set_hexpand(True) view_scroll.set_vexpand(True) # Context menu ui_dir = os.path.dirname(os.path.abspath(__file__)) ui_path = os.path.join(ui_dir, "layerswindow.xml") self.app.ui_manager.add_ui_from_file(ui_path) menu = self.app.ui_manager.get_widget("/LayersWindowPopup") menu.set_title(_("Layer")) self.connect("popup-menu", self._popup_menu_cb) menu.attach_to_widget(self, None) self._menu = menu self._layer_specific_ui_mergeid = None self._layer_specific_ui_class = None # Type column cell = Gtk.CellRendererPixbuf() col = Gtk.TreeViewColumn(_("Type")) col.pack_start(cell, expand=False) datafunc = layers.layer_type_pixbuf_datafunc col.set_cell_data_func(cell, datafunc) col.set_max_width(24) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(col) self._type_col = col # Name column cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) col = Gtk.TreeViewColumn(_("Name")) col.pack_start(cell, expand=True) datafunc = layers.layer_name_text_datafunc col.set_cell_data_func(cell, datafunc) col.set_expand(True) col.set_min_width(48) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) view.append_column(col) self._name_col = col # Visibility column cell = Gtk.CellRendererPixbuf() col = Gtk.TreeViewColumn(_("Visible")) col.pack_start(cell, expand=False) datafunc = layers.layer_visible_pixbuf_datafunc col.set_cell_data_func(cell, datafunc) col.set_max_width(24) view.append_column(col) self._visible_col = col # Locked column cell = Gtk.CellRendererPixbuf() col = Gtk.TreeViewColumn(_("Locked")) col.pack_start(cell, expand=False) datafunc = layers.layer_locked_pixbuf_datafunc col.set_cell_data_func(cell, datafunc) col.set_max_width(24) view.append_column(col) self._locked_col = col # View appearance view.set_show_expanders(True) view.set_enable_tree_lines(True) view.set_expander_column(self._name_col) # Main layout grid grid = Gtk.Grid() grid.set_row_spacing(widgets.SPACING_TIGHT) grid.set_column_spacing(widgets.SPACING) # Mode dropdown row = 0 label = Gtk.Label(label=_('Mode:')) label.set_tooltip_text( _("Blending mode: how the current layer combines with the " "layers underneath it.")) label.set_alignment(0, 0.5) label.set_hexpand(False) grid.attach(label, 0, row, 1, 1) store = Gtk.ListStore(str, str) for mode in range(NUM_COMBINE_MODES): label, desc = COMBINE_MODE_STRINGS.get(mode) store.append([str(mode), label]) combo = Gtk.ComboBox() combo.set_model(store) combo.set_hexpand(True) cell = Gtk.CellRendererText() combo.pack_start(cell) combo.add_attribute(cell, "text", 1) combo.set_id_column(0) self._layer_mode_combo = combo grid.attach(combo, 1, row, 5, 1) # Opacity slider row += 1 opacity_lbl = Gtk.Label(label=_('Opacity:')) opacity_lbl.set_tooltip_text( _("Layer opacity: how much of the current layer to use. " "Smaller values make it more transparent.")) opacity_lbl.set_alignment(0, 0.5) opacity_lbl.set_hexpand(False) adj = Gtk.Adjustment(lower=0, upper=100, step_incr=1, page_incr=10) self._opacity_scale = Gtk.HScale(adj) self._opacity_scale.set_draw_value(False) self._opacity_scale.set_hexpand(True) grid.attach(opacity_lbl, 0, row, 1, 1) grid.attach(self._opacity_scale, 1, row, 5, 1) # Layer list and controls row += 1 layersbox = Gtk.VBox() style = layersbox.get_style_context() style.add_class(Gtk.STYLE_CLASS_LINKED) style = view_scroll.get_style_context() style.set_junction_sides(Gtk.JunctionSides.BOTTOM) list_tools = inline_toolbar(self.app, [ ("NewLayerFG", "mypaint-add-symbolic"), ("RemoveLayer", "mypaint-remove-symbolic"), ("RaiseLayerInStack", "mypaint-up-symbolic"), ("LowerLayerInStack", "mypaint-down-symbolic"), ("DuplicateLayer", None), ("MergeLayerDown", None), ]) style = list_tools.get_style_context() style.set_junction_sides(Gtk.JunctionSides.TOP) layersbox.pack_start(view_scroll, True, True) layersbox.pack_start(list_tools, False, False) layersbox.set_hexpand(True) layersbox.set_vexpand(True) grid.attach(layersbox, 0, row, 6, 1) # Background layer controls row += 1 show_bg_btn = Gtk.CheckButton() change_bg_act = self.app.find_action("BackgroundWindow") change_bg_btn = widgets.borderless_button(action=change_bg_act) show_bg_act = self.app.find_action("ShowBackgroundToggle") show_bg_btn.set_related_action(show_bg_act) grid.attach(show_bg_btn, 0, row, 5, 1) grid.attach(change_bg_btn, 5, row, 1, 1) # Pack self.pack_start(grid, False, True, 0) # Updates self._processing_model_updates = False self._opacity_scale.connect('value-changed', self._opacity_scale_changed_cb) self._layer_mode_combo.connect('changed', self._layer_mode_combo_changed_cb) rootstack = docmodel.layer_stack rootstack.expand_layer += self._expand_layer_cb rootstack.collapse_layer += self._collapse_layer_cb rootstack.layer_content_changed += self._layer_content_changed rootstack.layer_properties_changed += self._layer_propchange_cb rootstack.current_layer_solo_changed += self._treeview_redraw_all rootstack.current_path_updated += self._current_path_updated_cb # Initial update self.connect("show", self._show_cb)
def __init__(self): from application import get_app Gtk.VBox.__init__(self) app = get_app() self.app = app self.doc = self.app.doc.model self.ani = app.doc.ani.model self.data = self.ani.timeline self.is_playing = False self.frame_width = 22 self.frame_width_active = 70 self.frame_height = 32 self.margin_top = 6 self.grid = Gtk.Grid() self.timeline_widget = TimelineWidget(self, app) self.scroll_timeline = Gtk.ScrolledWindow() self.scroll_timeline.add(self.timeline_widget) self.scroll_timeline.set_hexpand(True) self.scroll_timeline.set_vexpand(True) self.scroll_timeline.set_min_content_height(200) self.scroll_timeline.set_min_content_width(100) self.scroll_timeline.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) self.scroll_timeline.get_vscrollbar().connect('value-changed', self.on_scrolled) self.frame_widget = FrameWidget(self, app) self.scroll_frame = Gtk.ScrolledWindow() self.scroll_frame.set_vadjustment( self.scroll_timeline.get_vadjustment()) self.scroll_frame.get_vscrollbar().hide() self.scroll_frame.get_hscrollbar().hide() self.scroll_frame.add(self.frame_widget) self.scroll_frame.set_min_content_width(23) self.scroll_frame.set_vexpand(True) self.timeline_widget.connect('size_changed', self.frame_widget.resize) self.layer_widget = LayerWidget(self, self.app) self.scroll_layer = Gtk.ScrolledWindow() self.scroll_layer.set_hadjustment( self.scroll_timeline.get_hadjustment()) self.scroll_layer.get_vscrollbar().hide() self.scroll_layer.get_hscrollbar().hide() self.scroll_layer.add(self.layer_widget) self.scroll_layer.set_min_content_height(25) self.scroll_layer.set_hexpand(True) self.timeline_widget.connect('size_changed', self.layer_widget.resize) # try to use wheel value self.scroll_timeline.add_events(Gdk.EventMask.SCROLL_MASK) self.scroll_timeline.connect('scroll_event', self.on_scroll_zoom) self.size_adjustment = Gtk.Adjustment(value=self.frame_height, lower=1, upper=32, step_incr=1) self.size_adjustment.connect('value-changed', self.set_frame_height) self.size_adjustment.connect('value-changed', self.timeline_widget.resize) self.grid.attach(self.scroll_layer, 1, 0, 1, 1) self.grid.attach(self.scroll_frame, 0, 1, 1, 1) self.grid.attach(self.scroll_timeline, 1, 1, 1, 1) self.grid.set_property('margin', 3) # layer controls: from widgets import SPACING_CRAMPED self.tooltip_format = _( "<b>{blendingmode_name}</b>\n{blendingmode_description}") layer_ctrls_table = Gtk.Table() layer_ctrls_table.set_row_spacings(SPACING_CRAMPED) layer_ctrls_table.set_col_spacings(SPACING_CRAMPED) layer_ctrls_table.set_vexpand(False) row = 0 layer_mode_lbl = Gtk.Label(_('Mode:')) layer_mode_lbl.set_tooltip_text( _("Blending mode: how the current layer combines with the " "layers underneath it.")) layer_mode_lbl.set_alignment(0, 0.5) store = Gtk.ListStore(str, str) for mode in range(NUM_COMBINE_MODES): label, desc = COMBINE_MODE_STRINGS.get(mode) store.append([str(mode), label]) combo = Gtk.ComboBox() combo.set_model(store) combo.set_hexpand(True) cell = Gtk.CellRendererText() combo.pack_start(cell) combo.add_attribute(cell, "text", 1) combo.set_id_column(0) self.layer_mode_combo = combo layer_ctrls_table.attach(layer_mode_lbl, 0, 1, row, row + 1, Gtk.FILL) layer_ctrls_table.attach(self.layer_mode_combo, 1, 2, row, row + 1, Gtk.FILL | Gtk.EXPAND) row += 1 opacity_lbl = Gtk.Label(_('Opacity:')) opacity_lbl.set_tooltip_text( _("Layer opacity: how much of the current layer to use. Smaller " "values make it more transparent.")) opacity_lbl.set_alignment(0, 0.5) adj = Gtk.Adjustment(lower=0, upper=100, step_incr=1, page_incr=10) self.opacity_scale = Gtk.HScale(adj) self.opacity_scale.set_draw_value(False) layer_ctrls_table.attach(opacity_lbl, 0, 1, row, row + 1, Gtk.FILL) layer_ctrls_table.attach(self.opacity_scale, 1, 2, row, row + 1, Gtk.FILL | Gtk.EXPAND) row += 1 self.opacity_scale.connect('value-changed', self.on_opacity_changed) self.layer_mode_combo.connect('changed', self.on_layer_mode_changed) #(temporary) more layer controls~ self.duplicate_button = stock_button(Gtk.STOCK_COPY) self.duplicate_button.connect('clicked', self.on_duplicate) self.duplicate_button.set_tooltip_text(_('Duplicate layer')) self.merge_button = stock_button(Gtk.STOCK_DND_MULTIPLE) self.merge_button.connect('clicked', self.on_merge) self.merge_button.set_tooltip_text(_('Merge layer down')) temp_hbox = Gtk.HBox() temp_hbox.pack_start(self.duplicate_button) temp_hbox.pack_start(self.merge_button) layer_ctrls_table.attach(temp_hbox, 0, 2, row, row + 1, Gtk.FILL | Gtk.EXPAND) # playback controls: self.play_button = stock_button(Gtk.STOCK_MEDIA_PLAY) self.play_button.connect('clicked', self.on_animation_play) self.play_button.set_tooltip_text(_('Play animation')) self.pause_button = stock_button(Gtk.STOCK_MEDIA_PAUSE) self.pause_button.connect('clicked', self.on_animation_pause) self.pause_button.set_tooltip_text(_('Pause animation')) self.stop_button = stock_button(Gtk.STOCK_MEDIA_STOP) self.stop_button.connect('clicked', self.on_animation_stop) self.stop_button.set_tooltip_text(_('Stop animation')) # frames edit controls: cut_button = stock_button(Gtk.STOCK_CUT) cut_button.connect('clicked', self.on_cut) cut_button.set_tooltip_text(_('Cut cel')) self.cut_button = cut_button copy_button = stock_button(Gtk.STOCK_COPY) copy_button.connect('clicked', self.on_copy) copy_button.set_tooltip_text(_('Copy cel')) self.copy_button = copy_button paste_button = stock_button(Gtk.STOCK_PASTE) paste_button.connect('clicked', self.on_paste) paste_button.set_tooltip_text(_('Paste cel')) self.paste_button = paste_button framebuttons_hbox = Gtk.HBox() framebuttons_hbox.pack_start(self.play_button) framebuttons_hbox.pack_start(self.pause_button) framebuttons_hbox.pack_start(self.stop_button) framebuttons_hbox.pack_start(cut_button) framebuttons_hbox.pack_start(copy_button) framebuttons_hbox.pack_start(paste_button) self.pack_start(layer_ctrls_table, expand=False) self.pack_start(self.grid, expand=True) self.pack_start(framebuttons_hbox, expand=False) self.set_size_request(200, -1) self.doc.doc_observers.append(self.update)
def __init__(self): from application import get_app Gtk.VBox.__init__(self) app = get_app() self.app = app self.doc = self.app.doc.model self.ani = app.doc.ani.model self.data = self.ani.timeline self.is_playing = False self.frame_width = 22 self.frame_width_active = 70 self.frame_height = 32 self.margin_top = 6 self.grid = Gtk.Grid() self.timeline_widget = TimelineWidget(self, app) self.scroll_timeline = Gtk.ScrolledWindow() self.scroll_timeline.add(self.timeline_widget) self.scroll_timeline.set_hexpand(True) self.scroll_timeline.set_vexpand(True) self.scroll_timeline.set_min_content_height(200) self.scroll_timeline.set_min_content_width(100) self.scroll_timeline.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) self.scroll_timeline.get_vscrollbar().connect('value-changed', self.on_scrolled) self.frame_widget = FrameWidget(self, app) self.scroll_frame = Gtk.ScrolledWindow() self.scroll_frame.set_vadjustment(self.scroll_timeline.get_vadjustment()) self.scroll_frame.get_vscrollbar().hide() self.scroll_frame.get_hscrollbar().hide() self.scroll_frame.add(self.frame_widget) self.scroll_frame.set_min_content_width(23) self.scroll_frame.set_vexpand(True) self.timeline_widget.connect('size_changed', self.frame_widget.resize) self.layer_widget = LayerWidget(self, self.app) self.scroll_layer = Gtk.ScrolledWindow() self.scroll_layer.set_hadjustment(self.scroll_timeline.get_hadjustment()) self.scroll_layer.get_vscrollbar().hide() self.scroll_layer.get_hscrollbar().hide() self.scroll_layer.add(self.layer_widget) self.scroll_layer.set_min_content_height(25) self.scroll_layer.set_hexpand(True) self.timeline_widget.connect('size_changed', self.layer_widget.resize) # try to use wheel value self.scroll_timeline.add_events(Gdk.EventMask.SCROLL_MASK) self.scroll_timeline.connect('scroll_event', self.on_scroll_zoom) self.size_adjustment = Gtk.Adjustment(value=self.frame_height, lower=1, upper=32, step_incr=1) self.size_adjustment.connect('value-changed', self.set_frame_height) self.size_adjustment.connect('value-changed', self.timeline_widget.resize) self.grid.attach(self.scroll_layer, 1, 0, 1, 1) self.grid.attach(self.scroll_frame, 0, 1, 1, 1) self.grid.attach(self.scroll_timeline, 1, 1, 1, 1) self.grid.set_property('margin', 3) # layer controls: from widgets import SPACING_CRAMPED self.tooltip_format = _("<b>{blendingmode_name}</b>\n{blendingmode_description}") layer_ctrls_table = Gtk.Table() layer_ctrls_table.set_row_spacings(SPACING_CRAMPED) layer_ctrls_table.set_col_spacings(SPACING_CRAMPED) layer_ctrls_table.set_vexpand(False) row = 0 layer_mode_lbl = Gtk.Label(_('Mode:')) layer_mode_lbl.set_tooltip_text( _("Blending mode: how the current layer combines with the " "layers underneath it.")) layer_mode_lbl.set_alignment(0, 0.5) store = Gtk.ListStore(str, str) for mode in range(NUM_COMBINE_MODES): label, desc = COMBINE_MODE_STRINGS.get(mode) store.append([str(mode), label]) combo = Gtk.ComboBox() combo.set_model(store) combo.set_hexpand(True) cell = Gtk.CellRendererText() combo.pack_start(cell) combo.add_attribute(cell, "text", 1) combo.set_id_column(0) self.layer_mode_combo = combo layer_ctrls_table.attach(layer_mode_lbl, 0, 1, row, row+1, Gtk.FILL) layer_ctrls_table.attach(self.layer_mode_combo, 1, 2, row, row+1, Gtk.FILL|Gtk.EXPAND) row += 1 opacity_lbl = Gtk.Label(_('Opacity:')) opacity_lbl.set_tooltip_text( _("Layer opacity: how much of the current layer to use. Smaller " "values make it more transparent.")) opacity_lbl.set_alignment(0, 0.5) adj = Gtk.Adjustment(lower=0, upper=100, step_incr=1, page_incr=10) self.opacity_scale = Gtk.HScale(adj) self.opacity_scale.set_draw_value(False) layer_ctrls_table.attach(opacity_lbl, 0, 1, row, row+1, Gtk.FILL) layer_ctrls_table.attach(self.opacity_scale, 1, 2, row, row+1, Gtk.FILL|Gtk.EXPAND) row += 1 self.opacity_scale.connect('value-changed', self.on_opacity_changed) self.layer_mode_combo.connect('changed', self.on_layer_mode_changed) #(temporary) more layer controls~ self.duplicate_button = stock_button(Gtk.STOCK_COPY) self.duplicate_button.connect('clicked', self.on_duplicate) self.duplicate_button.set_tooltip_text(_('Duplicate layer')) self.merge_button = stock_button(Gtk.STOCK_DND_MULTIPLE) self.merge_button.connect('clicked', self.on_merge) self.merge_button.set_tooltip_text(_('Merge layer down')) temp_hbox = Gtk.HBox() temp_hbox.pack_start(self.duplicate_button) temp_hbox.pack_start(self.merge_button) layer_ctrls_table.attach(temp_hbox, 0, 2, row, row+1, Gtk.FILL|Gtk.EXPAND) # playback controls: self.play_button = stock_button(Gtk.STOCK_MEDIA_PLAY) self.play_button.connect('clicked', self.on_animation_play) self.play_button.set_tooltip_text(_('Play animation')) self.pause_button = stock_button(Gtk.STOCK_MEDIA_PAUSE) self.pause_button.connect('clicked', self.on_animation_pause) self.pause_button.set_tooltip_text(_('Pause animation')) self.stop_button = stock_button(Gtk.STOCK_MEDIA_STOP) self.stop_button.connect('clicked', self.on_animation_stop) self.stop_button.set_tooltip_text(_('Stop animation')) # frames edit controls: cut_button = stock_button(Gtk.STOCK_CUT) cut_button.connect('clicked', self.on_cut) cut_button.set_tooltip_text(_('Cut cel')) self.cut_button = cut_button copy_button = stock_button(Gtk.STOCK_COPY) copy_button.connect('clicked', self.on_copy) copy_button.set_tooltip_text(_('Copy cel')) self.copy_button = copy_button paste_button = stock_button(Gtk.STOCK_PASTE) paste_button.connect('clicked', self.on_paste) paste_button.set_tooltip_text(_('Paste cel')) self.paste_button = paste_button framebuttons_hbox = Gtk.HBox() framebuttons_hbox.pack_start(self.play_button) framebuttons_hbox.pack_start(self.pause_button) framebuttons_hbox.pack_start(self.stop_button) framebuttons_hbox.pack_start(cut_button) framebuttons_hbox.pack_start(copy_button) framebuttons_hbox.pack_start(paste_button) self.pack_start(layer_ctrls_table, expand=False) self.pack_start(self.grid, expand=True) self.pack_start(framebuttons_hbox, expand=False) self.set_size_request(200, -1) self.doc.doc_observers.append(self.update)