PIKApp/extensions/goat-exercises/goat-exercise-lua.lua

193 lines
6.1 KiB
Lua

#!/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)