Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
 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()
Ejemplo n.º 3
0
 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()
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
 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)
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
 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)
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
    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)