169 lines
6.2 KiB
Vala
169 lines
6.2 KiB
Vala
|
/* 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);
|
||
|
}
|
||
|
}
|