193 lines
6.1 KiB
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, config, 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)
|