Initial checkin of Pika from heckimp
This commit is contained in:
287
extensions/goat-exercises/goat-exercise-c.c
Normal file
287
extensions/goat-exercises/goat-exercise-c.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Goat exercise plug-in by Øyvind Kolås, pippin@gimp.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define PIKA_DISABLE_COMPAR_CRUFT
|
||||
|
||||
#include <libpika/pika.h>
|
||||
#include <libpika/pikaui.h>
|
||||
|
||||
#include "libpika/stdplugins-intl.h"
|
||||
|
||||
|
||||
#define PLUG_IN_BINARY "goat-exercise-c"
|
||||
#define PLUG_IN_SOURCE PLUG_IN_BINARY ".c"
|
||||
#define PLUG_IN_PROC "plug-in-goat-exercise-c"
|
||||
#define PLUG_IN_ROLE "goat-exercise-c"
|
||||
|
||||
#define GOAT_URI "https://gitlab.gnome.org/GNOME/pika/blob/master/extensions/goat-exercises/goat-exercise-c.c"
|
||||
|
||||
|
||||
typedef struct _Goat Goat;
|
||||
typedef struct _GoatClass GoatClass;
|
||||
|
||||
struct _Goat
|
||||
{
|
||||
PikaPlugIn parent_instance;
|
||||
};
|
||||
|
||||
struct _GoatClass
|
||||
{
|
||||
PikaPlugInClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
/* Declare local functions.
|
||||
*/
|
||||
|
||||
#define GOAT_TYPE (goat_get_type ())
|
||||
#define GOAT (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOAT_TYPE, Goat))
|
||||
|
||||
GType goat_get_type (void) G_GNUC_CONST;
|
||||
|
||||
static GList * goat_query_procedures (PikaPlugIn *plug_in);
|
||||
static PikaProcedure * goat_create_procedure (PikaPlugIn *plug_in,
|
||||
const gchar *name);
|
||||
|
||||
static PikaValueArray * goat_run (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args,
|
||||
gpointer run_data);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (Goat, goat, PIKA_TYPE_PLUG_IN)
|
||||
|
||||
PIKA_MAIN (GOAT_TYPE)
|
||||
|
||||
|
||||
static void
|
||||
goat_class_init (GoatClass *klass)
|
||||
{
|
||||
PikaPlugInClass *plug_in_class = PIKA_PLUG_IN_CLASS (klass);
|
||||
|
||||
plug_in_class->query_procedures = goat_query_procedures;
|
||||
plug_in_class->create_procedure = goat_create_procedure;
|
||||
}
|
||||
|
||||
static void
|
||||
goat_init (Goat *goat)
|
||||
{
|
||||
}
|
||||
|
||||
static GList *
|
||||
goat_query_procedures (PikaPlugIn *plug_in)
|
||||
{
|
||||
return g_list_append (NULL, g_strdup (PLUG_IN_PROC));
|
||||
}
|
||||
|
||||
static PikaProcedure *
|
||||
goat_create_procedure (PikaPlugIn *plug_in,
|
||||
const gchar *name)
|
||||
{
|
||||
PikaProcedure *procedure = NULL;
|
||||
|
||||
if (! strcmp (name, PLUG_IN_PROC))
|
||||
{
|
||||
procedure = pika_image_procedure_new (plug_in, name,
|
||||
PIKA_PDB_PROC_TYPE_PLUGIN,
|
||||
goat_run, NULL, NULL);
|
||||
|
||||
pika_procedure_set_image_types (procedure, "*");
|
||||
pika_procedure_set_sensitivity_mask (procedure,
|
||||
PIKA_PROCEDURE_SENSITIVE_DRAWABLE);
|
||||
|
||||
pika_procedure_set_menu_label (procedure, _("Exercise in _C minor"));
|
||||
pika_procedure_set_icon_name (procedure, PIKA_ICON_GEGL);
|
||||
pika_procedure_add_menu_path (procedure,
|
||||
"<Image>/Filters/Development/Goat exercises/");
|
||||
|
||||
pika_procedure_set_documentation (procedure,
|
||||
_("Exercise a goat in the C language"),
|
||||
"Takes a goat for a walk",
|
||||
PLUG_IN_PROC);
|
||||
pika_procedure_set_attribution (procedure,
|
||||
"Øyvind Kolås <pippin@gimp.org>",
|
||||
"Øyvind Kolås <pippin@gimp.org>",
|
||||
"21 march 2012");
|
||||
}
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
||||
static PikaValueArray *
|
||||
goat_run (PikaProcedure *procedure,
|
||||
PikaRunMode run_mode,
|
||||
PikaImage *image,
|
||||
gint n_drawables,
|
||||
PikaDrawable **drawables,
|
||||
const PikaValueArray *args,
|
||||
gpointer run_data)
|
||||
{
|
||||
PikaDrawable *drawable;
|
||||
PikaPDBStatusType status = PIKA_PDB_SUCCESS;
|
||||
gint x, y, width, height;
|
||||
|
||||
if (n_drawables != 1)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
g_set_error (&error, PIKA_PLUG_IN_ERROR, 0,
|
||||
_("Procedure '%s' only works with one drawable."),
|
||||
PLUG_IN_PROC);
|
||||
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_CALLING_ERROR,
|
||||
error);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawable = drawables[0];
|
||||
}
|
||||
|
||||
/* In interactive mode, display a dialog to advertise the exercise. */
|
||||
if (run_mode == PIKA_RUN_INTERACTIVE)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *box;
|
||||
GtkWidget *widget;
|
||||
GtkWidget *scrolled;
|
||||
GFile *file;
|
||||
GFileInputStream *input;
|
||||
gchar *head_text;
|
||||
gchar *path;
|
||||
GdkGeometry geometry;
|
||||
gchar source_text[4096];
|
||||
gssize read;
|
||||
gint response;
|
||||
|
||||
pika_ui_init (PLUG_IN_BINARY);
|
||||
dialog = pika_dialog_new (_("Exercise a goat (C)"), PLUG_IN_ROLE,
|
||||
NULL, GTK_DIALOG_USE_HEADER_BAR,
|
||||
pika_standard_help_func, PLUG_IN_PROC,
|
||||
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_Source"), GTK_RESPONSE_APPLY,
|
||||
_("_Run"), GTK_RESPONSE_OK,
|
||||
|
||||
NULL);
|
||||
geometry.min_aspect = 0.5;
|
||||
geometry.max_aspect = 1.0;
|
||||
gtk_window_set_geometry_hints (GTK_WINDOW (dialog), NULL,
|
||||
&geometry, GDK_HINT_ASPECT);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (box), 12);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
|
||||
box);
|
||||
gtk_widget_show (box);
|
||||
|
||||
head_text = g_strdup_printf (_("This plug-in is an exercise in '%s' "
|
||||
"to demo plug-in creation.\n"
|
||||
"Check out the last version "
|
||||
"of the source code online by "
|
||||
"clicking the \"Source\" button."),
|
||||
"C");
|
||||
widget = gtk_label_new (head_text);
|
||||
g_free (head_text);
|
||||
gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 1);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 1);
|
||||
gtk_widget_set_vexpand (GTK_WIDGET (scrolled), TRUE);
|
||||
gtk_widget_show (scrolled);
|
||||
|
||||
path = g_build_filename (pika_plug_in_directory (), "extensions",
|
||||
"technology.heckin.extension.goat-exercises", PLUG_IN_SOURCE,
|
||||
NULL);
|
||||
file = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
|
||||
widget = gtk_text_view_new ();
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (widget), GTK_WRAP_WORD);
|
||||
gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), FALSE);
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
|
||||
|
||||
input = g_file_read (file, NULL, NULL);
|
||||
|
||||
while ((read = g_input_stream_read (G_INPUT_STREAM (input),
|
||||
source_text, 4096, NULL, NULL)) &&
|
||||
read != -1)
|
||||
{
|
||||
gtk_text_buffer_insert_at_cursor (buffer, source_text, read);
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (scrolled), widget);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
while ((response = pika_dialog_run (PIKA_DIALOG (dialog))))
|
||||
{
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
break;
|
||||
}
|
||||
else if (response == GTK_RESPONSE_APPLY)
|
||||
{
|
||||
/* Show the code. */
|
||||
g_app_info_launch_default_for_uri (GOAT_URI, NULL, NULL);
|
||||
continue;
|
||||
}
|
||||
else /* CANCEL, CLOSE, DELETE_EVENT */
|
||||
{
|
||||
gtk_widget_destroy (dialog);
|
||||
return pika_procedure_new_return_values (procedure,
|
||||
PIKA_PDB_CANCEL,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pika_drawable_mask_intersect (drawable, &x, &y, &width, &height))
|
||||
{
|
||||
GeglBuffer *buffer;
|
||||
GeglBuffer *shadow_buffer;
|
||||
|
||||
gegl_init (NULL, NULL);
|
||||
|
||||
buffer = pika_drawable_get_buffer (drawable);
|
||||
shadow_buffer = pika_drawable_get_shadow_buffer (drawable);
|
||||
|
||||
gegl_render_op (buffer, shadow_buffer, "gegl:invert", NULL);
|
||||
|
||||
g_object_unref (shadow_buffer); /* flushes the shadow tiles */
|
||||
g_object_unref (buffer);
|
||||
|
||||
pika_drawable_merge_shadow (drawable, TRUE);
|
||||
pika_drawable_update (drawable, x, y, width, height);
|
||||
pika_displays_flush ();
|
||||
|
||||
gegl_exit ();
|
||||
}
|
||||
|
||||
return pika_procedure_new_return_values (procedure, status, NULL);
|
||||
}
|
193
extensions/goat-exercises/goat-exercise-gjs.js
Normal file
193
extensions/goat-exercises/goat-exercise-gjs.js
Normal file
@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env gjs
|
||||
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* hello-world.js
|
||||
* Copyright (C) Jehan
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const System = imports.system
|
||||
|
||||
imports.gi.versions.Pika = '3.0';
|
||||
const Pika = imports.gi.Pika;
|
||||
imports.gi.versions.PikaUi = '3.0';
|
||||
const PikaUi = imports.gi.PikaUi;
|
||||
imports.gi.versions.Gegl = '0.4';
|
||||
const Gegl = imports.gi.Gegl;
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
const Gtk = imports.gi.Gtk;
|
||||
imports.gi.versions.Gdk = '3.0';
|
||||
const Gdk = imports.gi.Gdk;
|
||||
|
||||
const GLib = imports.gi.GLib;
|
||||
const GObject = imports.gi.GObject;
|
||||
const Gio = imports.gi.Gio;
|
||||
|
||||
/* gjs's ARGV is not C-style. We must add the program name as first
|
||||
* value.
|
||||
*/
|
||||
ARGV.unshift(System.programInvocationName);
|
||||
|
||||
let url = "https://gitlab.gnome.org/GNOME/pika/blob/master/extensions/goat-exercises/goat-exercise-gjs.js";
|
||||
|
||||
function _(message) { return GLib.dgettext(null, message); }
|
||||
|
||||
var Goat = GObject.registerClass({
|
||||
GTypeName: 'Goat',
|
||||
}, class Goat extends Pika.PlugIn {
|
||||
|
||||
vfunc_query_procedures() {
|
||||
return ["plug-in-goat-exercise-gjs"];
|
||||
}
|
||||
|
||||
vfunc_create_procedure(name) {
|
||||
let procedure = Pika.ImageProcedure.new(this, name, Pika.PDBProcType.PLUGIN, this.run);
|
||||
|
||||
procedure.set_image_types("*");
|
||||
procedure.set_sensitivity_mask(Pika.ProcedureSensitivityMask.DRAWABLE);
|
||||
|
||||
procedure.set_menu_label(_("Exercise a JavaScript goat"));
|
||||
procedure.set_icon_name(PikaUi.ICON_GEGL);
|
||||
procedure.add_menu_path ('<Image>/Filters/Development/Goat exercises/');
|
||||
|
||||
procedure.set_documentation(_("Exercise a goat in the JavaScript language (GJS)"),
|
||||
_("Takes a goat for a walk in Javascript with the GJS interpreter"),
|
||||
name);
|
||||
procedure.set_attribution("Jehan", "Jehan", "2019");
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
||||
run(procedure, run_mode, image, drawables, args, run_data) {
|
||||
/* TODO: localization. */
|
||||
|
||||
if (drawables.length != 1) {
|
||||
let msg = `Procedure '${procedure.get_name()}' only works with one drawable.`;
|
||||
let error = GLib.Error.new_literal(Pika.PlugIn.error_quark(), 0, msg);
|
||||
return procedure.new_return_values(Pika.PDBStatusType.CALLING_ERROR, error)
|
||||
}
|
||||
|
||||
let drawable = drawables[0];
|
||||
|
||||
if (run_mode == Pika.RunMode.INTERACTIVE) {
|
||||
PikaUi.init("goat-exercise-gjs");
|
||||
/* TODO: help function and ID. */
|
||||
let dialog = new PikaUi.Dialog({
|
||||
title: _("Exercise a goat (JavaScript)"),
|
||||
role: "goat-exercise-JavaScript",
|
||||
use_header_bar: true,
|
||||
});
|
||||
dialog.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL);
|
||||
dialog.add_button(_("_Source"), Gtk.ResponseType.APPLY);
|
||||
dialog.add_button(_("_OK"), Gtk.ResponseType.OK);
|
||||
|
||||
let geometry = new Gdk.Geometry();
|
||||
geometry.min_aspect = 0.5;
|
||||
geometry.max_aspect = 1.0;
|
||||
dialog.set_geometry_hints (null, geometry, Gdk.WindowHints.ASPECT);
|
||||
|
||||
let box = new Gtk.Box({
|
||||
orientation: Gtk.Orientation.VERTICAL,
|
||||
spacing: 2
|
||||
});
|
||||
dialog.get_content_area().add(box);
|
||||
box.show();
|
||||
|
||||
let lang = "JavaScript (GJS)";
|
||||
/* XXX Can't we have nicer-looking multiline strings and
|
||||
* also in printf format like in C for sharing the same
|
||||
* string in localization?
|
||||
*/
|
||||
let head_text = `This plug-in is an exercise in '${lang}' to demo plug-in creation.\n` +
|
||||
`Check out the last version of the source code online by clicking the \"Source\" button.`;
|
||||
|
||||
let label = new Gtk.Label({label:head_text});
|
||||
box.pack_start(label, false, false, 1);
|
||||
label.show();
|
||||
|
||||
let contents = imports.byteArray.toString(GLib.file_get_contents(System.programInvocationName)[1]);
|
||||
if (contents) {
|
||||
let scrolled = new Gtk.ScrolledWindow();
|
||||
scrolled.set_vexpand (true);
|
||||
box.pack_start(scrolled, true, true, 1);
|
||||
scrolled.show();
|
||||
|
||||
let view = new Gtk.TextView();
|
||||
view.set_wrap_mode(Gtk.WrapMode.WORD);
|
||||
view.set_editable(false);
|
||||
let buffer = view.get_buffer();
|
||||
buffer.set_text(contents, -1);
|
||||
scrolled.add(view);
|
||||
view.show();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
let response = dialog.run();
|
||||
|
||||
if (response == Gtk.ResponseType.OK) {
|
||||
dialog.destroy();
|
||||
break;
|
||||
}
|
||||
else if (response == Gtk.ResponseType.APPLY) {
|
||||
Gio.app_info_launch_default_for_uri(url, null);
|
||||
continue;
|
||||
}
|
||||
else { /* CANCEL, CLOSE, DELETE_EVENT */
|
||||
dialog.destroy();
|
||||
return procedure.new_return_values(Pika.PDBStatusType.CANCEL, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let [ intersect, x, y, width, height ] = drawable.mask_intersect();
|
||||
if (intersect) {
|
||||
Gegl.init(null);
|
||||
|
||||
let buffer = drawable.get_buffer();
|
||||
let shadow_buffer = drawable.get_shadow_buffer();
|
||||
|
||||
let graph = new Gegl.Node();
|
||||
let input = graph.create_child("gegl:buffer-source");
|
||||
input.set_property("buffer", buffer);
|
||||
let invert = graph.create_child("gegl:invert");
|
||||
let output = graph.create_child("gegl:write-buffer");
|
||||
output.set_property("buffer", shadow_buffer);
|
||||
input.link(invert);
|
||||
invert.link(output);
|
||||
output.process();
|
||||
|
||||
/* This is extremely important in bindings, since we don't
|
||||
* unref buffers. If we don't explicitly flush a buffer, we
|
||||
* may left hanging forever. This step is usually done
|
||||
* during an unref().
|
||||
*/
|
||||
shadow_buffer.flush();
|
||||
|
||||
drawable.merge_shadow(true);
|
||||
drawable.update(x, y, width, height);
|
||||
Pika.displays_flush();
|
||||
}
|
||||
|
||||
return procedure.new_return_values(Pika.PDBStatusType.SUCCESS, null);
|
||||
}
|
||||
});
|
||||
|
||||
Pika.main(Goat.$gtype, ARGV);
|
192
extensions/goat-exercises/goat-exercise-lua.lua
Normal file
192
extensions/goat-exercises/goat-exercise-lua.lua
Normal file
@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env luajit
|
||||
|
||||
-- PIKA - Photo and Image Kooker Application
|
||||
-- Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
--
|
||||
-- goat-exercise-lua.lua
|
||||
-- Copyright (C) Jehan
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation; either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
local lgi = require 'lgi'
|
||||
|
||||
local GLib = lgi.GLib
|
||||
local GObject = lgi.GObject
|
||||
local Gio = lgi.Gio
|
||||
local Gegl = lgi.Gegl
|
||||
local Pika = lgi.Pika
|
||||
local PikaUi = lgi.PikaUi
|
||||
local Gtk = lgi.Gtk
|
||||
local Gdk = lgi.Gdk
|
||||
|
||||
local Goat = lgi.package 'Goat'
|
||||
local Goat = lgi.Goat
|
||||
|
||||
function N_(message)
|
||||
return message;
|
||||
end
|
||||
|
||||
function _(message)
|
||||
return GLib.dgettext(nil, message);
|
||||
end
|
||||
|
||||
function run(procedure, run_mode, image, drawables, args, run_data)
|
||||
-- procedure:new_return_values() crashes LGI so we construct the
|
||||
-- PikaValueArray manually.
|
||||
local retval = Pika.ValueArray(1)
|
||||
|
||||
if table.getn(drawables) ~= 1 then
|
||||
local calling_err = GObject.Value(Pika.PDBStatusType, Pika.PDBStatusType.CALLING_ERROR)
|
||||
local msg = "Procedure '%s' only works with one drawable."
|
||||
|
||||
msg = string.format(msg, procedure:get_name())
|
||||
|
||||
retval:append(calling_err)
|
||||
retval:append(GObject.Value(GObject.Type.STRING, msg))
|
||||
return retval
|
||||
end
|
||||
|
||||
local drawable = drawables[1]
|
||||
|
||||
-- Not sure why run_mode has become a string instead of testing
|
||||
-- against Pika.RunMode.INTERACTIVE.
|
||||
if run_mode == "INTERACTIVE" then
|
||||
PikaUi.init("goat-exercise-lua");
|
||||
local dialog = PikaUi.Dialog {
|
||||
title = _("Exercise a goat (Lua)"),
|
||||
role = "goat-exercise-Lua",
|
||||
use_header_bar = 1
|
||||
}
|
||||
dialog:add_button(_("_Cancel"), Gtk.ResponseType.CANCEL);
|
||||
dialog:add_button(_("_Source"), Gtk.ResponseType.APPLY);
|
||||
dialog:add_button(_("_OK"), Gtk.ResponseType.OK);
|
||||
|
||||
local geometry = Gdk.Geometry()
|
||||
geometry.min_aspect = 0.5;
|
||||
geometry.max_aspect = 1.0;
|
||||
dialog:set_geometry_hints (nil, geometry, Gdk.WindowHints.ASPECT);
|
||||
|
||||
local box = Gtk.Box {
|
||||
orientation = Gtk.Orientation.VERTICAL,
|
||||
spacing = 2
|
||||
}
|
||||
dialog:get_content_area():add(box)
|
||||
box:show()
|
||||
|
||||
local lang = "Lua"
|
||||
local head_text = _("This plug-in is an exercise in '%s' to demo plug-in creation.\n" ..
|
||||
"Check out the last version of the source code online by clicking the \"Source\" button.")
|
||||
|
||||
local label = Gtk.Label { label = string.format(head_text, lang) }
|
||||
box:pack_start(label, false, false, 1)
|
||||
label:show()
|
||||
|
||||
local contents = GLib.file_get_contents(arg[0])
|
||||
if (contents) then
|
||||
local scrolled = Gtk.ScrolledWindow()
|
||||
scrolled:set_vexpand (true)
|
||||
box:pack_start(scrolled, true, true, 1)
|
||||
scrolled:show()
|
||||
|
||||
local view = Gtk.TextView()
|
||||
view:set_wrap_mode(Gtk.WrapMode.WORD)
|
||||
view:set_editable(false)
|
||||
local buffer = view:get_buffer()
|
||||
buffer:set_text(contents, -1)
|
||||
scrolled:add(view)
|
||||
view:show()
|
||||
end
|
||||
|
||||
while (true) do
|
||||
local response = dialog:run()
|
||||
local url = 'https://gitlab.gnome.org/GNOME/pika/blob/master/extensions/goat-exercises/goat-exercise-lua.lua'
|
||||
|
||||
if response == Gtk.ResponseType.OK then
|
||||
dialog:destroy()
|
||||
break
|
||||
elseif (response == Gtk.ResponseType.APPLY) then
|
||||
Gio.app_info_launch_default_for_uri(url, nil);
|
||||
else -- CANCEL, CLOSE, DELETE_EVENT
|
||||
dialog:destroy()
|
||||
local cancel = GObject.Value(Pika.PDBStatusType, Pika.PDBStatusType.CANCEL)
|
||||
retval:append(cancel)
|
||||
return retval
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local x, y, width, height = drawable:mask_intersect()
|
||||
if width ~= nill and height ~= nil and width > 0 and height > 0 then
|
||||
Gegl.init(nil)
|
||||
|
||||
local buffer = drawable:get_buffer()
|
||||
local shadow_buffer = drawable:get_shadow_buffer()
|
||||
|
||||
local graph = Gegl.Node()
|
||||
local input = graph:create_child("gegl:buffer-source")
|
||||
input:set_property("buffer", GObject.Value(Gegl.Buffer, buffer))
|
||||
local invert = graph:create_child("gegl:invert")
|
||||
local output = graph:create_child("gegl:write-buffer")
|
||||
output:set_property("buffer", GObject.Value(Gegl.Buffer, shadow_buffer))
|
||||
input:link(invert)
|
||||
invert:link(output)
|
||||
output:process()
|
||||
|
||||
shadow_buffer:flush()
|
||||
|
||||
drawable:merge_shadow(true)
|
||||
drawable:update(x, y, width, height)
|
||||
Pika.displays_flush()
|
||||
end
|
||||
|
||||
local success = GObject.Value(Pika.PDBStatusType, Pika.PDBStatusType.SUCCESS)
|
||||
retval:append(success)
|
||||
return retval
|
||||
end
|
||||
|
||||
Goat:class('Exercise', Pika.PlugIn)
|
||||
|
||||
function Goat.Exercise:do_query_procedures()
|
||||
return { 'plug-in-goat-exercise-lua' }
|
||||
end
|
||||
|
||||
function Goat.Exercise:do_create_procedure(name)
|
||||
local procedure = Pika.ImageProcedure.new(self, name,
|
||||
Pika.PDBProcType.PLUGIN,
|
||||
run, nil)
|
||||
|
||||
procedure:set_image_types("*");
|
||||
procedure:set_sensitivity_mask(Pika.ProcedureSensitivityMask.DRAWABLE);
|
||||
|
||||
procedure:set_menu_label(_("Exercise a Lua goat"));
|
||||
procedure:set_icon_name(PikaUi.ICON_GEGL);
|
||||
procedure:add_menu_path('<Image>/Filters/Development/Goat exercises/');
|
||||
|
||||
procedure:set_documentation(_("Exercise a goat in the Lua language"),
|
||||
"Takes a goat for a walk in Lua",
|
||||
name);
|
||||
procedure:set_attribution("Jehan", "Jehan", "2019");
|
||||
|
||||
return procedure
|
||||
end
|
||||
|
||||
-- 'arg' is a Lua table. When automatically converted to an array, the
|
||||
-- value 0 is deleted (because Lua arrays start at 1!), which breaks
|
||||
-- Pika.main() call. So let's create our own array starting at 1.
|
||||
argv = {}
|
||||
for k, v in pairs(arg) do
|
||||
argv[k+1] = v
|
||||
end
|
||||
|
||||
Pika.main(GObject.Type.name(Goat.Exercise), argv)
|
167
extensions/goat-exercises/goat-exercise-py3.py
Normal file
167
extensions/goat-exercises/goat-exercise-py3.py
Normal file
@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import gi
|
||||
gi.require_version('Pika', '3.0')
|
||||
from gi.repository import Pika
|
||||
gi.require_version('PikaUi', '3.0')
|
||||
from gi.repository import PikaUi
|
||||
gi.require_version('Gegl', '0.4')
|
||||
from gi.repository import Gegl
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GLib
|
||||
from gi.repository import Gio
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
def N_(message): return message
|
||||
def _(message): return GLib.dgettext(None, message)
|
||||
|
||||
class Goat (Pika.PlugIn):
|
||||
## PikaPlugIn virtual methods ##
|
||||
def do_query_procedures(self):
|
||||
return [ "plug-in-goat-exercise-python" ]
|
||||
|
||||
def do_create_procedure(self, name):
|
||||
procedure = Pika.ImageProcedure.new(self, name,
|
||||
Pika.PDBProcType.PLUGIN,
|
||||
self.run, None)
|
||||
|
||||
procedure.set_image_types("*")
|
||||
procedure.set_sensitivity_mask (Pika.ProcedureSensitivityMask.DRAWABLE)
|
||||
|
||||
procedure.set_menu_label(_("Exercise a goat and a python"))
|
||||
procedure.set_icon_name(PikaUi.ICON_GEGL)
|
||||
procedure.add_menu_path('<Image>/Filters/Development/Goat exercises/')
|
||||
|
||||
procedure.set_documentation(_("Exercise a goat in the Python 3 language"),
|
||||
_("Takes a goat for a walk in Python 3"),
|
||||
name)
|
||||
procedure.set_attribution("Jehan", "Jehan", "2019")
|
||||
|
||||
return procedure
|
||||
|
||||
def run(self, procedure, run_mode, image, n_drawables, drawables, args, run_data):
|
||||
if n_drawables != 1:
|
||||
msg = _("Procedure '{}' only works with one drawable.").format(procedure.get_name())
|
||||
error = GLib.Error.new_literal(Pika.PlugIn.error_quark(), msg, 0)
|
||||
return procedure.new_return_values(Pika.PDBStatusType.CALLING_ERROR, error)
|
||||
else:
|
||||
drawable = drawables[0]
|
||||
|
||||
if run_mode == Pika.RunMode.INTERACTIVE:
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
gi.require_version('Gdk', '3.0')
|
||||
from gi.repository import Gdk
|
||||
|
||||
PikaUi.init("goat-exercise-py3.py")
|
||||
|
||||
dialog = PikaUi.Dialog(use_header_bar=True,
|
||||
title=_("Exercise a goat (Python 3)"),
|
||||
role="goat-exercise-Python3")
|
||||
|
||||
dialog.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
|
||||
dialog.add_button(_("_Source"), Gtk.ResponseType.APPLY)
|
||||
dialog.add_button(_("_OK"), Gtk.ResponseType.OK)
|
||||
|
||||
geometry = Gdk.Geometry()
|
||||
geometry.min_aspect = 0.5
|
||||
geometry.max_aspect = 1.0
|
||||
dialog.set_geometry_hints(None, geometry, Gdk.WindowHints.ASPECT)
|
||||
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
|
||||
dialog.get_content_area().add(box)
|
||||
box.show()
|
||||
|
||||
# XXX We use printf-style string for sharing the localized
|
||||
# string. You may just use recommended Python format() or
|
||||
# any style you like in your plug-ins.
|
||||
head_text=_("This plug-in is an exercise in '%s' to "
|
||||
"demo plug-in creation.\nCheck out the last "
|
||||
"version of the source code online by clicking "
|
||||
"the \"Source\" button.") % ("Python 3")
|
||||
label = Gtk.Label(label=head_text)
|
||||
box.pack_start(label, False, False, 1)
|
||||
label.show()
|
||||
|
||||
contents = None
|
||||
# Get the file contents Python-style instead of using
|
||||
# GLib.file_get_contents() which returns bytes result, and
|
||||
# when converting to string, get newlines as text contents.
|
||||
# Rather than wasting time to figure this out, use Python
|
||||
# core API!
|
||||
with open(os.path.realpath(__file__), 'r') as f:
|
||||
contents = f.read()
|
||||
|
||||
if contents is not None:
|
||||
scrolled = Gtk.ScrolledWindow()
|
||||
scrolled.set_vexpand (True)
|
||||
box.pack_start(scrolled, True, True, 1)
|
||||
scrolled.show()
|
||||
|
||||
view = Gtk.TextView()
|
||||
view.set_wrap_mode(Gtk.WrapMode.WORD)
|
||||
view.set_editable(False)
|
||||
buffer = view.get_buffer()
|
||||
buffer.set_text(contents, -1)
|
||||
scrolled.add(view)
|
||||
view.show()
|
||||
|
||||
while (True):
|
||||
response = dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
dialog.destroy()
|
||||
break
|
||||
elif response == Gtk.ResponseType.APPLY:
|
||||
url = "https://gitlab.gnome.org/GNOME/pika/-/blob/master/extensions/goat-exercises/goat-exercise-py3.py"
|
||||
Gio.app_info_launch_default_for_uri(url, None)
|
||||
continue
|
||||
else:
|
||||
dialog.destroy()
|
||||
return procedure.new_return_values(Pika.PDBStatusType.CANCEL,
|
||||
GLib.Error())
|
||||
|
||||
intersect, x, y, width, height = drawable.mask_intersect()
|
||||
if intersect:
|
||||
Gegl.init(None)
|
||||
|
||||
buffer = drawable.get_buffer()
|
||||
shadow_buffer = drawable.get_shadow_buffer()
|
||||
|
||||
graph = Gegl.Node()
|
||||
input = graph.create_child("gegl:buffer-source")
|
||||
input.set_property("buffer", buffer)
|
||||
invert = graph.create_child("gegl:invert")
|
||||
output = graph.create_child("gegl:write-buffer")
|
||||
output.set_property("buffer", shadow_buffer)
|
||||
input.link(invert)
|
||||
invert.link(output)
|
||||
output.process()
|
||||
|
||||
# This is extremely important in bindings, since we don't
|
||||
# unref buffers. If we don't explicitly flush a buffer, we
|
||||
# may left hanging forever. This step is usually done
|
||||
# during an unref().
|
||||
shadow_buffer.flush()
|
||||
|
||||
drawable.merge_shadow(True)
|
||||
drawable.update(x, y, width, height)
|
||||
Pika.displays_flush()
|
||||
|
||||
return procedure.new_return_values(Pika.PDBStatusType.SUCCESS, GLib.Error())
|
||||
|
||||
Pika.main(Goat.__gtype__, sys.argv)
|
168
extensions/goat-exercises/goat-exercise-vala.vala
Normal file
168
extensions/goat-exercises/goat-exercise-vala.vala
Normal file
@ -0,0 +1,168 @@
|
||||
/* PIKA - Photo and Image Kooker Application
|
||||
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
||||
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
||||
*
|
||||
* Original copyright, applying to most contents (license remains unchanged):
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* hello-world.vala
|
||||
* Copyright (C) Niels De Graef <nielsdegraef@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
private const string PLUG_IN_PROC = "plug-in-goat-exercise-vala";
|
||||
private const string PLUG_IN_ROLE = "goat-exercise-vala";
|
||||
private const string PLUG_IN_BINARY = "goat-exercise-vala";
|
||||
private const string PLUG_IN_SOURCE = PLUG_IN_BINARY + ".vala";
|
||||
private const string URL = "https://gitlab.gnome.org/GNOME/pika/blob/master/extensions/goat-exercises/goat-exercise-vala.vala";
|
||||
|
||||
public int main(string[] args) {
|
||||
return Pika.main(typeof(Goat), args);
|
||||
}
|
||||
|
||||
public class Goat : Pika.PlugIn {
|
||||
|
||||
public override GLib.List<string> query_procedures() {
|
||||
GLib.List<string> procs = null;
|
||||
procs.append(PLUG_IN_PROC);
|
||||
return procs;
|
||||
}
|
||||
|
||||
public override Pika.Procedure create_procedure(string name) {
|
||||
assert(name == PLUG_IN_PROC);
|
||||
|
||||
var procedure = new Pika.ImageProcedure(this, name, Pika.PDBProcType.PLUGIN, this.run);
|
||||
procedure.set_image_types("RGB*, INDEXED*, GRAY*");
|
||||
procedure.set_sensitivity_mask(Pika.ProcedureSensitivityMask.DRAWABLE);
|
||||
procedure.set_menu_label(_("Exercise a Vala goat"));
|
||||
procedure.set_documentation(_("Exercise a goat in the Vala language"),
|
||||
_("Takes a goat for a walk in Vala"),
|
||||
PLUG_IN_PROC);
|
||||
procedure.add_menu_path("<Image>/Filters/Development/Goat exercises/");
|
||||
procedure.set_attribution("Niels De Graef", "Niels De Graef", "2020");
|
||||
procedure.set_icon_name(PikaUi.ICON_GEGL);
|
||||
|
||||
return procedure;
|
||||
}
|
||||
|
||||
public Pika.ValueArray run(Pika.Procedure procedure,
|
||||
Pika.RunMode run_mode,
|
||||
Pika.Image image,
|
||||
Pika.Drawable[] drawables,
|
||||
Pika.ValueArray args) {
|
||||
var drawable = drawables[0];
|
||||
|
||||
if (run_mode == Pika.RunMode.INTERACTIVE) {
|
||||
PikaUi.init(PLUG_IN_BINARY);
|
||||
|
||||
var dialog =
|
||||
new PikaUi.Dialog(_("Exercise a goat (Vala)"),
|
||||
PLUG_IN_ROLE,
|
||||
null,
|
||||
Gtk.DialogFlags.USE_HEADER_BAR,
|
||||
PikaUi.standard_help_func,
|
||||
PLUG_IN_PROC,
|
||||
_("_Cancel"), Gtk.ResponseType.CANCEL,
|
||||
_("_Source"), Gtk.ResponseType.APPLY,
|
||||
_("_Run"), Gtk.ResponseType.OK,
|
||||
null);
|
||||
|
||||
var geometry = Gdk.Geometry();
|
||||
geometry.min_aspect = 0.5;
|
||||
geometry.max_aspect = 1.0;
|
||||
dialog.set_geometry_hints(null, geometry, Gdk.WindowHints.ASPECT);
|
||||
|
||||
var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 12);
|
||||
box.border_width = 12;
|
||||
dialog.get_content_area().add(box);
|
||||
box.show();
|
||||
|
||||
var head_text =
|
||||
_("This plug-in is an exercise in '%s' to demo plug-in creation.\nCheck out the last version of the source code online by clicking the \"Source\" button.")
|
||||
.printf("Vala");
|
||||
|
||||
var label = new Gtk.Label(head_text);
|
||||
box.pack_start(label, false, false, 1);
|
||||
label.show();
|
||||
|
||||
|
||||
string file = Path.build_filename(Pika.PlugIn.directory(), "extensions", "technology.heckin.extension.goat-exercises", PLUG_IN_SOURCE);
|
||||
string contents;
|
||||
try {
|
||||
FileUtils.get_contents(file, out contents);
|
||||
} catch (Error err) {
|
||||
contents = "Couldn't get file contents: %s".printf(err.message);
|
||||
}
|
||||
|
||||
var scrolled = new Gtk.ScrolledWindow(null, null);
|
||||
scrolled.vexpand = true;
|
||||
box.pack_start(scrolled, true, true, 1);
|
||||
scrolled.show();
|
||||
|
||||
var view = new Gtk.TextView();
|
||||
view.wrap_mode = Gtk.WrapMode.WORD;
|
||||
view.editable = false;
|
||||
view.buffer.text = contents;
|
||||
scrolled.add(view);
|
||||
view.show();
|
||||
|
||||
while (true) {
|
||||
var response = dialog.run();
|
||||
|
||||
if (response == Gtk.ResponseType.OK) {
|
||||
dialog.destroy();
|
||||
break;
|
||||
} else if (response == Gtk.ResponseType.APPLY) {
|
||||
try {
|
||||
Gtk.show_uri_on_window(dialog, URL, Gdk.CURRENT_TIME);
|
||||
} catch (Error err) {
|
||||
warning("Couldn't launch browser for %s: %s", URL, err.message);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
dialog.destroy();
|
||||
return procedure.new_return_values(Pika.PDBStatusType.CANCEL, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int x, y, width, height;
|
||||
if (!drawable.mask_intersect(out x, out y, out width, out height)) {
|
||||
var error = new GLib.Error.literal(GLib.Quark.from_string("goat-error-quark"), 0,
|
||||
"No pixels to process in the selected area.");
|
||||
return procedure.new_return_values(Pika.PDBStatusType.CALLING_ERROR, error);
|
||||
}
|
||||
|
||||
unowned string[]? argv = null;
|
||||
Gegl.init(ref argv);
|
||||
|
||||
{
|
||||
var buffer = drawable.get_buffer();
|
||||
var shadow_buffer = drawable.get_shadow_buffer();
|
||||
Gegl.render_op(buffer, shadow_buffer, "gegl:invert", null);
|
||||
// We don't need this line, since shadow_buffer is unreffed
|
||||
// at the end of this block.
|
||||
// No block? Then you still need to uncomment the following line
|
||||
// shadow_buffer.flush();
|
||||
}
|
||||
|
||||
drawable.merge_shadow(true);
|
||||
drawable.update(x, y, width, height);
|
||||
Pika.displays_flush();
|
||||
Gegl.exit();
|
||||
|
||||
return procedure.new_return_values(Pika.PDBStatusType.SUCCESS, null);
|
||||
}
|
||||
}
|
114
extensions/goat-exercises/meson.build
Normal file
114
extensions/goat-exercises/meson.build
Normal file
@ -0,0 +1,114 @@
|
||||
# C version
|
||||
|
||||
extension_name = 'technology.heckin.extension.goat-exercises'
|
||||
plug_in_name = 'goat-exercise'
|
||||
|
||||
plugin_sources = [
|
||||
'goat-exercise-c.c',
|
||||
]
|
||||
|
||||
if platform_windows
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
'--define', 'ORIGINALFILENAME_STR="@0@"'.format(plug_in_name + '-c.exe'),
|
||||
'--define', 'INTERNALNAME_STR="@0@"' .format(plug_in_name),
|
||||
'--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
],
|
||||
)
|
||||
endif
|
||||
|
||||
exe = executable(plug_in_name + '-c',
|
||||
plugin_sources,
|
||||
dependencies: [
|
||||
libpikaui_dep,
|
||||
math,
|
||||
],
|
||||
install: true,
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
|
||||
# XXX This is so ugly!
|
||||
# From meson 0.54.0, we will be able to use exe.name().
|
||||
plug_ins = exe.full_path().split('/')[-1].split('\\')[-1]
|
||||
|
||||
install_data(
|
||||
'goat-exercise-c.c',
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
|
||||
# Vala version
|
||||
|
||||
if have_vala and have_gobject_introspection
|
||||
exe = executable('goat-exercise-vala',
|
||||
'goat-exercise-vala.vala',
|
||||
include_directories: [ rootInclude, ],
|
||||
dependencies: [
|
||||
libpika_vapi, libpikaui_vapi, gtk3, gegl, math,
|
||||
],
|
||||
c_args: [
|
||||
'-DGETTEXT_PACKAGE="@0@"'.format('technology.heckin.extension.goat-exercises'),
|
||||
],
|
||||
install: true,
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
plug_ins = plug_ins + ':' + exe.full_path().split('/')[-1].split('\\')[-1]
|
||||
|
||||
install_data(
|
||||
'goat-exercise-vala.vala',
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
endif
|
||||
|
||||
# Python 3 (pygobject) version.
|
||||
|
||||
if have_python
|
||||
install_data(
|
||||
'goat-exercise-py3.py',
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
plug_ins = plug_ins + ':goat-exercise-py3.py'
|
||||
endif
|
||||
|
||||
# Javascript (GJS) version.
|
||||
|
||||
if have_javascript
|
||||
install_data(
|
||||
'goat-exercise-gjs.js',
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
plug_ins = plug_ins + ':goat-exercise-gjs.js'
|
||||
endif
|
||||
|
||||
# Lua (lua-jit + LGI) version.
|
||||
|
||||
if have_lua
|
||||
install_data(
|
||||
'goat-exercise-lua.lua',
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
||||
plug_ins = plug_ins + ':goat-exercise-lua.lua'
|
||||
endif
|
||||
|
||||
# Generate the AppData.
|
||||
|
||||
conf = configuration_data()
|
||||
conf.set('GOAT_EXERCISES', plug_ins)
|
||||
|
||||
appdatafilename = 'technology.heckin.extension.goat-exercises.metainfo.xml'
|
||||
appdatafilein = configure_file(
|
||||
input : appdatafilename + '.in.in',
|
||||
output: appdatafilename + '.in',
|
||||
configuration: conf,
|
||||
)
|
||||
|
||||
appdatafile = i18n.merge_file(
|
||||
input : [ appdatafilein, ],
|
||||
output: appdatafilename,
|
||||
po_dir: po_plug_ins_dir,
|
||||
install: true,
|
||||
install_dir: pikaplugindir / 'extensions' / extension_name,
|
||||
)
|
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="addon">
|
||||
<id>technology.heckin.extension.goat-exercises</id>
|
||||
<extends>technology.heckin.PIKA</extends>
|
||||
<name>Goat Exercises</name>
|
||||
<summary>Official Demo Plug-ins</summary>
|
||||
<description>
|
||||
<p>
|
||||
This extension provides a set of basic examples to demonstrate
|
||||
how to create your own plug-ins.
|
||||
Each plug-in does the same thing, except it is developed in a
|
||||
different programming language.
|
||||
They all create a GTK dialog with a text view displaying their own code
|
||||
(hence also demonstrating how to package data) and a button which calls
|
||||
a GEGL operation on the active layer.
|
||||
</p>
|
||||
</description>
|
||||
<url type="homepage">https://pika.org</url>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<releases>
|
||||
<release version="1.0.0" date="2020-10-08" />
|
||||
</releases>
|
||||
<requires>
|
||||
<id version="2.99.0" compare="ge">technology.heckin.PIKA</id>
|
||||
</requires>
|
||||
<metadata>
|
||||
<value key="PIKA::plug-in-path">@GOAT_EXERCISES@</value>
|
||||
</metadata>
|
||||
</component>
|
Reference in New Issue
Block a user