[pitivi] previewers: Add Title clip Previewer
- From: Alexandru Băluț <alexbalut src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pitivi] previewers: Add Title clip Previewer
- Date: Tue, 24 Mar 2020 12:11:42 +0000 (UTC)
commit ebf36119f153cefdd71c56cd9af6ed83b0d8f1f4
Author: Diego Garcia Gangl <dnicolas gmail com>
Date: Sat May 4 20:59:39 2019 -0300
previewers: Add Title clip Previewer
Fixes #2311
pitivi/check.py | 1 +
pitivi/timeline/elements.py | 10 +++--
pitivi/timeline/previewers.py | 99 ++++++++++++++++++++++++++++++++++++++++++-
pitivi/utils/ui.py | 7 +--
4 files changed, 108 insertions(+), 9 deletions(-)
---
diff --git a/pitivi/check.py b/pitivi/check.py
index 41daec7d..193f5301 100644
--- a/pitivi/check.py
+++ b/pitivi/check.py
@@ -444,6 +444,7 @@ HARD_DEPENDENCIES = [GICheck(version_required="3.20.0"),
GstPluginDependency("gdkpixbuf"),
ClassicDependency("matplotlib"),
GIDependency("Peas", apiversion="1.0"),
+ GIDependency("PangoCairo", apiversion="1.0"),
]
SOFT_DEPENDENCIES = (
diff --git a/pitivi/timeline/elements.py b/pitivi/timeline/elements.py
index c2abdbd3..6f70041d 100644
--- a/pitivi/timeline/elements.py
+++ b/pitivi/timeline/elements.py
@@ -33,6 +33,7 @@ from pitivi.configure import get_pixmap_dir
from pitivi.effects import ALLOWED_ONLY_ONCE_EFFECTS
from pitivi.timeline.previewers import AudioPreviewer
from pitivi.timeline.previewers import ImagePreviewer
+from pitivi.timeline.previewers import TitlePreviewer
from pitivi.timeline.previewers import VideoPreviewer
from pitivi.undo.timeline import CommitTimelineFinalizingAction
from pitivi.utils.loggable import Loggable
@@ -964,6 +965,11 @@ class TitleSource(VideoSource):
return spec
return None
+ def _get_previewer(self):
+ previewer = TitlePreviewer(self._ges_elem)
+ previewer.get_style_context().add_class("TitleSource")
+ return previewer
+
def _get_default_position(self):
return {"posx": 0,
"posy": 0,
@@ -984,8 +990,6 @@ class VideoUriSource(VideoSource):
previewer = ImagePreviewer(self._ges_elem, self.timeline.app.settings.previewers_max_cpu)
else:
previewer = VideoPreviewer(self._ges_elem, self.timeline.app.settings.previewers_max_cpu)
- previewer.get_style_context().add_class("VideoUriSource")
-
return previewer
def _get_default_mixing_property(self):
@@ -1012,8 +1016,6 @@ class AudioUriSource(TimelineElement):
def _get_previewer(self):
previewer = AudioPreviewer(self._ges_elem, self.timeline.app.settings.previewers_max_cpu)
- previewer.get_style_context().add_class("AudioPreviewer")
-
return previewer
def _get_background(self):
diff --git a/pitivi/timeline/previewers.py b/pitivi/timeline/previewers.py
index 78a33e96..6641f56e 100644
--- a/pitivi/timeline/previewers.py
+++ b/pitivi/timeline/previewers.py
@@ -20,6 +20,7 @@ import hashlib
import os
import random
import sqlite3
+from gettext import gettext as _
import cairo
import numpy
@@ -30,6 +31,8 @@ from gi.repository import GLib
from gi.repository import GObject
from gi.repository import Gst
from gi.repository import Gtk
+from gi.repository import Pango
+from gi.repository import PangoCairo
from pitivi.settings import GlobalSettings
from pitivi.settings import xdg_cache_home
@@ -368,11 +371,9 @@ class Previewer(GObject.Object):
def start_generation(self):
"""Starts preview generation."""
- raise NotImplementedError
def stop_generation(self):
"""Stops preview generation."""
- raise NotImplementedError
def become_controlled(self):
"""Lets the PreviewGeneratorManager control our execution."""
@@ -414,6 +415,8 @@ class ImagePreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
Zoomable.__init__(self)
Loggable.__init__(self)
+ self.get_style_context().add_class("VideoPreviewer")
+
self.ges_elem = ges_elem
# Guard against malformed URIs
@@ -810,6 +813,8 @@ class VideoPreviewer(Gtk.Layout, AssetPreviewer, Zoomable):
Zoomable.__init__(self)
AssetPreviewer.__init__(self, get_proxy_target(ges_elem), max_cpu_usage)
+ self.get_style_context().add_class("VideoPreviewer")
+
self.ges_elem = ges_elem
self.thumbs = {}
@@ -905,6 +910,9 @@ class Thumbnail(Gtk.Image):
def __init__(self, width, height):
Gtk.Image.__init__(self)
+
+ self.get_style_context().add_class("Thumbnail")
+
self.props.width_request = width
self.props.height_request = height
@@ -1117,6 +1125,8 @@ class AudioPreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
Zoomable.__init__(self)
Loggable.__init__(self)
+ self.get_style_context().add_class("AudioPreviewer")
+
self.pipeline = None
self._wavebin = None
@@ -1313,3 +1323,88 @@ class AudioPreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
"""Stops preview generation and cleans the object."""
self.stop_generation()
Zoomable.__del__(self)
+
+
+class TitlePreviewer(Gtk.Layout, Previewer, Zoomable, Loggable):
+ """Title Clip previewer using Pango to draw text on the clip."""
+
+ __gsignals__ = PREVIEW_GENERATOR_SIGNALS
+
+ def __init__(self, ges_elem):
+ Gtk.Layout.__init__(self)
+ Previewer.__init__(self, GES.TrackType.VIDEO, None)
+ Zoomable.__init__(self)
+ Loggable.__init__(self)
+
+ self.get_style_context().add_class("TitlePreviewer")
+
+ self.ges_elem = ges_elem
+ font = Gtk.Settings.get_default().get_property("gtk-font-name")
+ self._font_desc = Pango.font_description_from_string(font)
+ self._selected = False
+
+ self.ges_elem.connect("deep-notify", self._ges_elem_deep_notify_cb)
+
+ def _ges_elem_deep_notify_cb(self, ges_element, gst_element, pspec):
+ """Forces a redraw when the clip's text is changed."""
+ if pspec.name == "text":
+ self.queue_draw()
+
+ def do_draw(self, context):
+ rect = Gdk.cairo_get_clip_rectangle(context)[1]
+ context.set_source_rgb(1, 1, 1)
+
+ # Get text
+ res, text = self.ges_elem.get_child_property("text")
+ if res:
+ text = text.strip().split("\n", 1)[0]
+ if not res or not text:
+ text = _("Title Clip")
+
+ # Adapt to RTL/LTR direction
+ direction = Pango.unichar_direction(text[0])
+ if direction in (Pango.Direction.LTR, Pango.Direction.NEUTRAL):
+ stops = (0, 1)
+ x_pos = 10
+ grad = cairo.LinearGradient(rect.width * 0.66, 0,
+ rect.width * 0.91, 0)
+ else:
+ stops = (1, 0)
+ x_pos = -10
+ grad = cairo.LinearGradient(rect.width * 0.09, 0,
+ rect.width * 0.34, 0)
+
+ # Gradient to make text "fade out"
+ if self._selected:
+ color = (0.14, 0.133, 0.15)
+ else:
+ color = (0.368, 0.305, 0.4)
+
+ grad.add_color_stop_rgba(stops[0], color[0], color[1], color[2], 0)
+ grad.add_color_stop_rgba(stops[1], color[0], color[1], color[2], 1)
+
+ # Setup Pango layout
+ layout = PangoCairo.create_layout(context)
+ layout.set_auto_dir(True)
+ layout.set_font_description(self._font_desc)
+ layout.set_width(rect.width * Pango.SCALE)
+
+ # Prevent lines from being wrapped
+ layout.set_ellipsize(Pango.EllipsizeMode.END)
+
+ # Draw text
+ layout.set_text(text, -1)
+ context.move_to(x_pos, (rect.height / 2) - 11)
+ PangoCairo.show_layout(context, layout)
+
+ # Draw gradient
+ context.rectangle(0, 0, rect.width, rect.height)
+ context.set_source(grad)
+ context.fill()
+
+ def set_selected(self, select):
+ self._selected = select
+
+ def release(self):
+ # Nothing to release
+ pass
diff --git a/pitivi/utils/ui.py b/pitivi/utils/ui.py
index 0afb07cc..ffdbb43d 100644
--- a/pitivi/utils/ui.py
+++ b/pitivi/utils/ui.py
@@ -210,13 +210,14 @@ EDITOR_PERSPECTIVE_CSS = """
}
- .VideoUriSource image {
+ .Thumbnail {
transition: opacity 200ms linear;
opacity: 1;
}
- .VideoUriSource:selected image,
- .AudioUriSource:selected .AudioPreviewer {
+ .VideoPreviewer:selected,
+ .AudioPreviewer:selected,
+ .TitlePreviewer:selected {
opacity: 0.15;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]