[pitivi] docs: Add plugins documentation



commit dcd92940b0f36cbb495efb8582df8d2acd3ecb6a
Author: Alexandru Băluț <alexandru balut gmail com>
Date:   Wed Mar 20 01:25:02 2019 +0100

    docs: Add plugins documentation
    
    Based on documentation written by cfoch.
    
    Fixes #2089

 docs/Advanced_plugin.md                         |  75 ++++++++++++++++++++++++
 docs/Plugins.md                                 |  72 +++++++++++++++++++++++
 docs/images/Plugins_Gap_Remover-1.gif           | Bin 0 -> 95859 bytes
 docs/images/Plugins_Hello_World_preferences.png | Bin 0 -> 4506 bytes
 docs/sitemap.txt                                |   2 +
 5 files changed, 149 insertions(+)
---
diff --git a/docs/Advanced_plugin.md b/docs/Advanced_plugin.md
new file mode 100644
index 00000000..b1d0ea86
--- /dev/null
+++ b/docs/Advanced_plugin.md
@@ -0,0 +1,75 @@
+---
+short-description: An advanced plugin example
+...
+
+# How to interact with the timeline
+
+Let's add a button for removing the gaps between clips!
+
+![](images/Plugins_Gap_Remover-1.gif)
+
+Follow the steps in the [hello world example](Plugins.md) to create a plugin directory and a plugin info 
file. What's left is to create the Python module with the logic.
+
+## Adding the new button
+
+Since the button is related to the timeline, we add it in the timeline toolbar, at the right of the timeline.
+
+```python
+from gi.repository import GObject
+from gi.repository import Gtk
+from gi.repository import Peas
+
+class GapRemover(GObject.Object, Peas.Activatable):
+
+    object = GObject.Property(type=GObject.Object)
+
+    def do_activate(self):
+        self.app = self.object.app
+        self.button = Gtk.ToolButton.new_from_stock(Gtk.STOCK_STRIKETHROUGH)
+        self.button.set_tooltip_text("Remove gaps between clips")
+        self.button.show()
+
+        toolbar = self.app.gui.editor.timeline_ui.toolbar
+        toolbar.add(self.button)
+```
+
+At this point, you can re-start Pitivi, activate the plugin and notice the new button in the UI!
+
+## Making it dance
+
+The interesting part is the `__clicked_cb` callback method, which is connected to the button's "clicked" 
signal:
+
+```python
+
+    def do_activate(self):
+        ...
+        self.button.connect("clicked", self.__clicked_cb)
+
+    def __clicked_cb(self, unused_button):
+        timeline = self.app.gui.editor.timeline_ui.timeline
+        clips = sorted(timeline.selection, key=lambda x : x.get_start())
+        if len(clips) >= 2:
+            timeline.current_group.ungroup(False)  # https://gitlab.gnome.org/GNOME/pitivi/issues/2288
+            previous = clips[0]
+            for clip in clips[1:]:
+                clip.set_start(previous.get_start() + previous.get_duration())
+                previous = clip
+```
+
+Finally, we can add some cleanup logic when the plugin is deactivated, because we're nice:
+
+```python
+    def do_deactivate(self):
+        self.app.gui.editor.timeline_ui.toolbar.remove(self.button)
+```
+
+## Making it shine
+
+The plugin can be improved by:
+- Associating the action with a keyboard shortcut.
+- Checking whether the clips are [grouped](http://www.pitivi.org/manual/selectiongrouping.html), because the 
entire group moves when a clip in the group is moved, so they should be dealt with somehow.
+- Making the operation undoable by wrapping it in a `with self.app.action_log.started("add clip", 
toplevel=True):`.
+- Disabling the button automatically when `timeline.selection` contains less than two clips.
+- Making it work for the entire timeline in case there is no selection.
+
+Check out the Pitivi code and the [GES API](http://lazka.github.io/pgi-docs/#GES-1.0) to see what can be 
done, and tell us what you are hacking!
\ No newline at end of file
diff --git a/docs/Plugins.md b/docs/Plugins.md
new file mode 100644
index 00000000..c09d9e81
--- /dev/null
+++ b/docs/Plugins.md
@@ -0,0 +1,72 @@
+---
+short-description: The plugin system, and a Hello World plugin
+...
+
+# Plugins
+
+Pitivi's [Plugin Manager](https://gitlab.gnome.org/GNOME/pitivi/blob/master/pitivi/pluginmanager.py) is 
based on [libpeas](https://wiki.gnome.org/Projects/Libpeas). Currently we only support plugins written in 
Python 3.
+
+## Location
+
+There are two directories where Pitivi is looking for plugins. One is the system plugins directory, where 
normally you'll find the [plugins we ship by 
default](https://gitlab.gnome.org/GNOME/pitivi/blob/master/plugins). The other is the user plugins directory, 
where you can hack your own plugin.
+
+Depending on how you installed Pitivi, these directories can have different locations. In the Plugins tab in 
the Preferences window you should be able to find out the location of the two directories.
+
+## Hello World
+
+Each plugin must have its own directory, so start with creating a directory, for example `hello`.
+
+To provide some info about the plugin, create a [plugin info 
file](https://developer.gnome.org/libpeas/stable/PeasPluginInfo.html), for example `hello/world.plugin`:
+
+```ini
+[Plugin]
+Name=Hello World
+Description=A very simple plugin.
+Authors=...
+website=...
+Copyright=...
+
+Loader=python3
+Module=world
+```
+
+
+The "Loader=python3" and "Module=world" above specify the plugin is loaded from the `hello/world.py` Python 
module. The module should contain at least one class implementing the 
[Peas.Activatable](https://lazka.github.io/pgi-docs/#Peas-1.0/classes/Activatable.html#Peas.Activatable) 
interface:
+
+```python
+from gi.repository import GObject
+from gi.repository import Peas
+
+class HelloWorld(GObject.Object, Peas.Activatable):
+
+    object = GObject.Property(type=GObject.Object)
+
+    def do_activate(self):
+        print("Hello World!", self.object)
+
+    def do_deactivate(self):
+        print("Bye!")
+```
+
+Start Pitivi, activate the plugin in Preferences > Plugins, and notice "Hello World!" in the console.
+
+![](images/Plugins_Hello_World_preferences.png)
+
+## API
+
+There is no API really. Plugins have full access to the entire app. Needless to say, they will break sooner 
or later, as we refactor parts of the app. Use them to have fun and try things out. If you think more people 
would be interested in them, [talk with us](http://www.pitivi.org/?go=contact) to see what we can do to help 
them survive.
+
+The entire Pitivi instance is provided through `self.object.app` in the `do_activate` method:
+
+```python
+    def do_activate(self):
+        # Keep a reference to the app so you can access later
+        # the current project, for example.
+        self.app = self.object.app
+
+        # You can access the MainWindow to add your widgets, or
+        # change the behavior of the existing widgets.
+        main_window = self.app.gui
+```
+
+For an advanced example, check out how to create a plugin for [automating the operations with the clips in 
the timeline](Advanced_plugin.md).
diff --git a/docs/images/Plugins_Gap_Remover-1.gif b/docs/images/Plugins_Gap_Remover-1.gif
new file mode 100644
index 00000000..ff8ba2a6
Binary files /dev/null and b/docs/images/Plugins_Gap_Remover-1.gif differ
diff --git a/docs/images/Plugins_Hello_World_preferences.png b/docs/images/Plugins_Hello_World_preferences.png
new file mode 100644
index 00000000..3c728972
Binary files /dev/null and b/docs/images/Plugins_Hello_World_preferences.png differ
diff --git a/docs/sitemap.txt b/docs/sitemap.txt
index cd7c0ce0..01b1ad00 100644
--- a/docs/sitemap.txt
+++ b/docs/sitemap.txt
@@ -12,6 +12,8 @@ index.md
        release.md
        Architecture.md
                GES.md
+       Plugins.md
+               Advanced_plugin.md
        crossplatform.md
                Mac_OS_X.md
        Praise.md


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]