2.99 libgimp: add GimpResource, GimpBrush, GimpPropWidgetBrush

So procedures can declare args and GimpProcedureDialog show chooser
widgets

Fix so is no error dialog on id_is_valid for resources

Palette.pdb changes and testing

Memory mgt changes

Gradient pdb

Font and Pattern tests

Test  brush, palette

Cleanup, remove generator

Rebase, edit docs, install test-dialog.py

Whitespace, and fix failed distcheck

Fix some clang-format, fix fail distcheck

Fix distcheck

Cleanup from review Jehan
This commit is contained in:
lloyd konneker 2022-09-05 19:28:35 -04:00 committed by Jehan
parent 60fa18137d
commit d720375e97
74 changed files with 8517 additions and 4270 deletions

View File

@ -36,6 +36,13 @@
#include "vectors/gimpvectors.h"
/* resource types */
#include "gimpbrush.h"
#include "gimpgradient.h"
#include "gimppalette.h"
#include "gimppattern.h"
#include "text/gimpfont.h"
/*
* GIMP_TYPE_PARAM_STRING
@ -341,5 +348,12 @@ gimp_param_spec_enum_exclude_value (GimpParamSpecEnum *espec,
#define gimp_image_is_valid(image) TRUE
#define gimp_item_is_valid(item) TRUE
#define gimp_display_is_valid(display) TRUE
/* resource types. */
#define gimp_brush_is_valid(image) TRUE
#define gimp_font_is_valid(image) TRUE
#define gimp_gradient_is_valid(image) TRUE
#define gimp_palette_is_valid(image) TRUE
#define gimp_pattern_is_valid(image) TRUE
#include "../../libgimp/gimpparamspecs-body.c"
#include "../../libgimp/gimpparamspecs-body-resource.c"

View File

@ -85,6 +85,7 @@ void gimp_param_spec_enum_exclude_value (GimpParamSpecEnum *espec,
*/
#define GIMP_COMPILATION
#include "../../libgimp/gimpparamspecs.h"
#include "../../libgimp/gimpparamspecs-resource.h"
#undef GIMP_COMPILATION

View File

@ -51,6 +51,7 @@ libappinternal_procs_a_SOURCES = \
edit-cmds.c \
file-cmds.c \
floating-sel-cmds.c \
font-cmds.c \
font-select-cmds.c \
fonts-cmds.c \
gimp-cmds.c \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

102
app/pdb/font-cmds.c Normal file
View File

@ -0,0 +1,102 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
*
* 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/>.
*/
/* NOTE: This file is auto-generated by pdbgen.pl. */
#include "config.h"
#include "stamp-pdbgen.h"
#include <gegl.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "libgimpbase/gimpbase.h"
#include "pdb-types.h"
#include "core/gimp.h"
#include "core/gimpparamspecs.h"
#include "gimppdb.h"
#include "gimppdb-utils.h"
#include "gimpprocedure.h"
#include "internal-procs.h"
static GimpValueArray *
font_id_is_valid_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
GimpValueArray *return_vals;
const gchar *id;
gboolean valid = FALSE;
id = g_value_get_string (gimp_value_array_index (args, 0));
valid = (gimp_pdb_get_font (gimp, id, error) != NULL);
/* When ID is not valid, NULL is returned and error is set.
* Clear error so GIMP not display error dialog.
*/
g_clear_error (error);
return_vals = gimp_procedure_get_return_values (procedure, TRUE, NULL);
g_value_set_boolean (gimp_value_array_index (return_vals, 1), valid);
return return_vals;
}
void
register_font_procs (GimpPDB *pdb)
{
GimpProcedure *procedure;
/*
* gimp-font-id-is-valid
*/
procedure = gimp_procedure_new (font_id_is_valid_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-font-id-is-valid");
gimp_procedure_set_static_help (procedure,
"Whether the ID is a valid reference to installed data.",
"Returns TRUE if this ID is valid.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Lloyd Konneker",
"Lloyd Konneker",
"2022");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("id",
"id",
"The font ID",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
gimp_procedure_add_return_value (procedure,
g_param_spec_boolean ("valid",
"valid",
"TRUE if the font ID is valid",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
}

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
#include "internal-procs.h"
/* 767 procedures registered total */
/* 772 procedures registered total */
void
internal_procs_init (GimpPDB *pdb)
@ -52,6 +52,7 @@ internal_procs_init (GimpPDB *pdb)
register_edit_procs (pdb);
register_file_procs (pdb);
register_floating_sel_procs (pdb);
register_font_procs (pdb);
register_font_select_procs (pdb);
register_fonts_procs (pdb);
register_gimp_procs (pdb);

View File

@ -39,6 +39,7 @@ void register_dynamics_procs (GimpPDB *pdb);
void register_edit_procs (GimpPDB *pdb);
void register_file_procs (GimpPDB *pdb);
void register_floating_sel_procs (GimpPDB *pdb);
void register_font_procs (GimpPDB *pdb);
void register_font_select_procs (GimpPDB *pdb);
void register_fonts_procs (GimpPDB *pdb);
void register_gimp_procs (GimpPDB *pdb);

View File

@ -23,6 +23,7 @@ libappinternalprocs_sources = [
'edit-cmds.c',
'file-cmds.c',
'floating-sel-cmds.c',
'font-cmds.c',
'font-select-cmds.c',
'fonts-cmds.c',
'gimp-cmds.c',

View File

@ -57,26 +57,21 @@ palette_new_invoker (GimpProcedure *procedure,
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
gchar *actual_name = NULL;
GimpPalette *palette = NULL;
name = g_value_get_string (gimp_value_array_index (args, 0));
if (success)
{
GimpData *data = gimp_data_factory_data_new (gimp->palette_factory,
palette = (GimpPalette*) gimp_data_factory_data_new (gimp->palette_factory,
context, name);
if (data)
actual_name = g_strdup (gimp_object_get_name (data));
else
success = FALSE;
}
return_vals = gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
if (success)
g_value_take_string (gimp_value_array_index (return_vals, 1), actual_name);
g_value_set_object (gimp_value_array_index (return_vals, 1), palette);
return return_vals;
}
@ -91,27 +86,17 @@ palette_duplicate_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
gchar *copy_name = NULL;
GimpPalette *palette;
GimpPalette *palette_copy = NULL;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
{
GimpPalette *palette_copy = (GimpPalette *)
gimp_data_factory_data_duplicate (gimp->palette_factory,
GIMP_DATA (palette));
if (palette_copy)
copy_name = g_strdup (gimp_object_get_name (palette_copy));
else
success = FALSE;
}
else
palette_copy = (GimpPalette *)
gimp_data_factory_data_duplicate (gimp->palette_factory, GIMP_DATA (palette));
/* Assert the copy has a unique name. */
if (!palette_copy)
success = FALSE;
}
@ -119,7 +104,34 @@ palette_duplicate_invoker (GimpProcedure *procedure,
error ? *error : NULL);
if (success)
g_value_take_string (gimp_value_array_index (return_vals, 1), copy_name);
g_value_set_object (gimp_value_array_index (return_vals, 1), palette_copy);
return return_vals;
}
static GimpValueArray *
palette_id_is_valid_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
GimpValueArray *return_vals;
const gchar *id;
gboolean valid = FALSE;
id = g_value_get_string (gimp_value_array_index (args, 0));
valid = (gimp_pdb_get_palette (gimp, id, GIMP_PDB_DATA_ACCESS_READ, error) != NULL);
/* When ID is not valid, NULL is returned and error is set.
* Clear error so GIMP not display error dialog.
*/
g_clear_error (error);
return_vals = gimp_procedure_get_return_values (procedure, TRUE, NULL);
g_value_set_boolean (gimp_value_array_index (return_vals, 1), valid);
return return_vals;
}
@ -134,31 +146,32 @@ palette_rename_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
const gchar *new_name;
gchar *actual_name = NULL;
GimpPalette *palette_renamed = NULL;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
new_name = g_value_get_string (gimp_value_array_index (args, 1));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_RENAME, error);
/* Rename the palette in app. */
gimp_object_set_name (GIMP_OBJECT (palette), new_name);
/* Assert GIMP might have set a name different from new_name. */
if (palette)
{
gimp_object_set_name (GIMP_OBJECT (palette), new_name);
actual_name = g_strdup (gimp_object_get_name (palette));
}
else
success = FALSE;
/* Return a reference.
* The wire protocol will create a new proxy on the plugin side.
* We don't need an alias here, except to make clear
* that we are returning the same real object as passed.
*/
palette_renamed = palette;
}
return_vals = gimp_procedure_get_return_values (procedure, success,
error ? *error : NULL);
if (success)
g_value_take_string (gimp_value_array_index (return_vals, 1), actual_name);
g_value_set_object (gimp_value_array_index (return_vals, 1), palette_renamed);
return return_vals;
}
@ -172,14 +185,12 @@ palette_delete_invoker (GimpProcedure *procedure,
GError **error)
{
gboolean success = TRUE;
const gchar *name;
GimpPalette *palette;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette && gimp_data_is_deletable (GIMP_DATA (palette)))
success = gimp_data_factory_data_delete (gimp->palette_factory,
GIMP_DATA (palette),
@ -202,19 +213,14 @@ palette_is_editable_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
gboolean editable = FALSE;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
editable = gimp_data_is_writable (GIMP_DATA (palette));
else
success = FALSE;
editable = gimp_data_is_writable (GIMP_DATA (palette));
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -227,28 +233,23 @@ palette_is_editable_invoker (GimpProcedure *procedure,
}
static GimpValueArray *
palette_get_info_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
palette_get_color_count_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
gint num_colors = 0;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
num_colors = gimp_palette_get_n_colors (palette);
else
success = FALSE;
num_colors = gimp_palette_get_n_colors (palette);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -270,33 +271,26 @@ palette_get_colors_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
gint num_colors = 0;
GimpRGB *colors = NULL;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
GList *list = gimp_palette_get_colors (palette);
gint i;
if (palette)
num_colors = gimp_palette_get_n_colors (palette);
colors = g_new (GimpRGB, num_colors);
for (i = 0; i < num_colors; i++, list = g_list_next (list))
{
GList *list = gimp_palette_get_colors (palette);
gint i;
GimpPaletteEntry *entry = list->data;
num_colors = gimp_palette_get_n_colors (palette);
colors = g_new (GimpRGB, num_colors);
for (i = 0; i < num_colors; i++, list = g_list_next (list))
{
GimpPaletteEntry *entry = list->data;
colors[i] = entry->color;
}
colors[i] = entry->color;
}
else
success = FALSE;
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -321,19 +315,14 @@ palette_get_columns_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
gint num_columns = 0;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
num_columns = gimp_palette_get_columns (palette);
else
success = FALSE;
num_columns = gimp_palette_get_columns (palette);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -354,17 +343,15 @@ palette_set_columns_invoker (GimpProcedure *procedure,
GError **error)
{
gboolean success = TRUE;
const gchar *name;
GimpPalette *palette;
gint columns;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
columns = g_value_get_int (gimp_value_array_index (args, 1));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
gimp_palette_set_columns (palette, columns);
else
success = FALSE;
@ -384,28 +371,29 @@ palette_add_entry_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
const gchar *entry_name;
GimpRGB color;
gint entry_num = 0;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
entry_name = g_value_get_string (gimp_value_array_index (args, 1));
gimp_value_get_rgb (gimp_value_array_index (args, 2), &color);
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
/* Must check writeable here, because add_entry does not fail when not writeable. */
if (gimp_data_is_writable (GIMP_DATA (palette)))
{
GimpPaletteEntry *entry =
gimp_palette_add_entry (palette, -1, entry_name, &color);
/* -1 for the index means append. */
GimpPaletteEntry *entry = gimp_palette_add_entry (palette, -1, entry_name, &color);
entry_num = gimp_palette_get_entry_position (palette, entry);
}
else
success = FALSE;
{
success = FALSE;
}
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -426,17 +414,15 @@ palette_delete_entry_invoker (GimpProcedure *procedure,
GError **error)
{
gboolean success = TRUE;
const gchar *name;
GimpPalette *palette;
gint entry_num;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
entry_num = g_value_get_int (gimp_value_array_index (args, 1));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
{
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
@ -463,26 +449,19 @@ palette_entry_get_color_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
gint entry_num;
GimpRGB color = { 0.0, 0.0, 0.0, 1.0 };
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
entry_num = g_value_get_int (gimp_value_array_index (args, 1));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (palette)
{
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (entry)
color = entry->color;
else
success = FALSE;
}
if (entry)
color = entry->color;
else
success = FALSE;
}
@ -505,19 +484,17 @@ palette_entry_set_color_invoker (GimpProcedure *procedure,
GError **error)
{
gboolean success = TRUE;
const gchar *name;
GimpPalette *palette;
gint entry_num;
GimpRGB color;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
entry_num = g_value_get_int (gimp_value_array_index (args, 1));
gimp_value_get_rgb (gimp_value_array_index (args, 2), &color);
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
success = gimp_palette_set_entry_color (palette, entry_num, &color);
else
success = FALSE;
@ -537,26 +514,19 @@ palette_entry_get_name_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPalette *palette;
gint entry_num;
gchar *entry_name = NULL;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
entry_num = g_value_get_int (gimp_value_array_index (args, 1));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (palette)
{
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (entry)
entry_name = g_strdup (entry->name);
else
success = FALSE;
}
if (entry)
entry_name = g_strdup (entry->name);
else
success = FALSE;
}
@ -579,19 +549,17 @@ palette_entry_set_name_invoker (GimpProcedure *procedure,
GError **error)
{
gboolean success = TRUE;
const gchar *name;
GimpPalette *palette;
gint entry_num;
const gchar *entry_name;
name = g_value_get_string (gimp_value_array_index (args, 0));
palette = g_value_get_object (gimp_value_array_index (args, 0));
entry_num = g_value_get_int (gimp_value_array_index (args, 1));
entry_name = g_value_get_string (gimp_value_array_index (args, 2));
if (success)
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
success = gimp_palette_set_entry_name (palette, entry_num, entry_name);
else
success = FALSE;
@ -614,7 +582,7 @@ register_palette_procs (GimpPDB *pdb)
"gimp-palette-new");
gimp_procedure_set_static_help (procedure,
"Creates a new palette",
"This procedure creates a new, uninitialized palette",
"Creates a new palette. The new palette has no color entries. You must add color entries for a user to choose. The actual name might be different than the requested name, when the requested name is already in use.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
@ -628,12 +596,11 @@ register_palette_procs (GimpPDB *pdb)
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("actual-name",
"actual name",
"The actual new palette name",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
@ -645,26 +612,54 @@ register_palette_procs (GimpPDB *pdb)
"gimp-palette-duplicate");
gimp_procedure_set_static_help (procedure,
"Duplicates a palette",
"This procedure creates an identical palette by a different name",
"Returns a copy having a different, unique ID.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_palette ("palette-copy",
"palette copy",
"A copy of the palette.",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-palette-id-is-valid
*/
procedure = gimp_procedure_new (palette_id_is_valid_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-id-is-valid");
gimp_procedure_set_static_help (procedure,
"Whether the ID is a valid reference to installed data.",
"Returns TRUE if this ID is valid.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Lloyd Konneker",
"Lloyd Konneker",
"2022");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("id",
"id",
"The palette ID",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("copy-name",
"copy name",
"The name of the palette's copy",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
g_param_spec_boolean ("valid",
"valid",
"TRUE if the palette ID is valid",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
@ -676,33 +671,32 @@ register_palette_procs (GimpPDB *pdb)
"gimp-palette-rename");
gimp_procedure_set_static_help (procedure,
"Rename a palette",
"This procedure renames a palette",
"Renames a palette. The name is the same as the ID. When the proposed name is already used, GIMP generates a unique name, which get_id() will return.\n"
"Returns a reference to a renamed palette, which you should assign to the original var or a differently named var. Any existing references will be invalid. Resources in plugins are proxies holding an ID, which can be invalid when the resource is renamed.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("new-name",
"new name",
"The new name of the palette",
"The requested new name of the palette",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("actual-name",
"actual name",
"The actual new name of the palette",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette-renamed",
"palette renamed",
"A reference to the renamed palette.",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
@ -714,19 +708,18 @@ register_palette_procs (GimpPDB *pdb)
"gimp-palette-delete");
gimp_procedure_set_static_help (procedure,
"Deletes a palette",
"This procedure deletes a palette",
"Deletes a palette. Returns an error if the palette is not deletable. Deletes the palette's data. You should not use the palette afterwards.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
@ -737,7 +730,7 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-is-editable");
gimp_procedure_set_static_help (procedure,
"Tests if palette can be edited",
"Whether the palette can be edited",
"Returns TRUE if you have permission to change the palette",
NULL);
gimp_procedure_set_static_attribution (procedure,
@ -745,12 +738,11 @@ register_palette_procs (GimpPDB *pdb)
"Bill Skaggs",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
g_param_spec_boolean ("editable",
"editable",
@ -761,26 +753,25 @@ register_palette_procs (GimpPDB *pdb)
g_object_unref (procedure);
/*
* gimp-palette-get-info
* gimp-palette-get-color-count
*/
procedure = gimp_procedure_new (palette_get_info_invoker);
procedure = gimp_procedure_new (palette_get_color_count_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-get-info");
"gimp-palette-get-color-count");
gimp_procedure_set_static_help (procedure,
"Retrieve information about the specified palette.",
"This procedure retrieves information about the specified palette. This includes the name, and the number of colors.",
"Get the count of colors in the palette.",
"Returns the number of colors in the palette.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
g_param_spec_int ("num-colors",
"num colors",
@ -797,20 +788,19 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-get-colors");
gimp_procedure_set_static_help (procedure,
"Gets all colors from the specified palette.",
"This procedure retrieves all color entries of the specified palette.",
"Gets colors in the palette.",
"Returns an array of colors in the palette.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Sven Neumann <sven@gimp.org>",
"Sven Neumann",
"2006");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
g_param_spec_int ("num-colors",
"num colors",
@ -832,20 +822,19 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-get-columns");
gimp_procedure_set_static_help (procedure,
"Retrieves the number of columns to use to display this palette",
"This procedures retrieves the preferred number of columns to use when the palette is being displayed.",
"Gets the number of columns used to display the palette",
"Gets the preferred number of columns to display the palette.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Sven Neumann <sven@gimp.org>",
"Sven Neumann",
"2005");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
g_param_spec_int ("num-columns",
"num columns",
@ -862,20 +851,19 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-set-columns");
gimp_procedure_set_static_help (procedure,
"Sets the number of columns to use when displaying the palette",
"This procedures controls how many colors are shown per row when the palette is being displayed. This value can only be changed if the palette is writable. The maximum allowed value is 64.",
"Sets the number of columns used to display the palette",
"Set the number of colors shown per row when the palette is displayed. Returns an error when the palette is not editable. The maximum allowed value is 64.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Sven Neumann <sven@gimp.org>",
"Sven Neumann",
"2005");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("columns",
"columns",
@ -892,31 +880,30 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-add-entry");
gimp_procedure_set_static_help (procedure,
"Adds a palette entry to the specified palette.",
"This procedure adds an entry to the specified palette. It returns an error if the entry palette does not exist.",
"Appends an entry to the palette.",
"Appends an entry to the palette. Neither color nor name must be unique within the palette. When name is the empty string, this sets the entry name to \"Untitled\". Returns the index of the entry. Returns an error when palette is not editable.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("entry-name",
"entry name",
"The name of the entry",
"A name for the entry",
FALSE, TRUE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
gimp_param_spec_rgb ("color",
"color",
"The new entry's color color",
"The color for the added entry.",
FALSE,
NULL,
GIMP_PARAM_READWRITE));
@ -936,24 +923,23 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-delete-entry");
gimp_procedure_set_static_help (procedure,
"Deletes a palette entry from the specified palette.",
"This procedure deletes an entry from the specified palette. It returns an error if the entry palette does not exist.",
"Deletes an entry from the palette.",
"Deletes an entry from the palette. Returns an error if the index is out or range. Returns an error if the palette is not editable.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("entry-num",
"entry num",
"The index of the added entry",
"The index of the entry to delete",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
@ -966,30 +952,29 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-entry-get-color");
gimp_procedure_set_static_help (procedure,
"Gets the specified palette entry from the specified palette.",
"This procedure retrieves the color of the zero-based entry specified for the specified palette. It returns an error if the entry does not exist.",
"Gets the color of an entry in the palette.",
"Returns the color of the entry at the given zero-based index into the palette. Returns an error when the index is out of range.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("entry-num",
"entry num",
"The entry to retrieve",
"The index of the entry to get the color of.",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_rgb ("color",
"color",
"The color requested",
"The color at the index.",
FALSE,
NULL,
GIMP_PARAM_READWRITE));
@ -1003,24 +988,23 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-entry-set-color");
gimp_procedure_set_static_help (procedure,
"Sets the specified palette entry in the specified palette.",
"This procedure sets the color of the zero-based entry specified for the specified palette. It returns an error if the entry does not exist.",
"Sets the color of an entry in the palette.",
"Sets the color of the entry at the zero-based index into the palette. Returns an error when the index is out of range. Returns an error when the palette is not editable.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("entry-num",
"entry num",
"The entry to retrieve",
"The entry to get",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
@ -1040,30 +1024,29 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-entry-get-name");
gimp_procedure_set_static_help (procedure,
"Gets the specified palette entry from the specified palette.",
"This procedure retrieves the name of the zero-based entry specified for the specified palette. It returns an error if the entry does not exist.",
"Gets the name of an entry in the palette.",
"Gets the name of the entry at the zero-based index into the palette. Returns an error when the index is out of range.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("entry-num",
"entry num",
"The entry to retrieve",
"The entry to get",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
gimp_param_spec_string ("entry-name",
"entry name",
"The name requested",
"The name of the entry.",
FALSE, FALSE, FALSE,
NULL,
GIMP_PARAM_READWRITE));
@ -1077,24 +1060,23 @@ register_palette_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-palette-entry-set-name");
gimp_procedure_set_static_help (procedure,
"Sets the specified palette entry in the specified palette.",
"This procedure sets the name of the zero-based entry specified for the specified palette. It returns an error if the entry does not exist.",
"Sets the name of an entry in the palette.",
"Sets the name of the entry at the zero-based index into the palette. Returns an error if the index is out or range. Returns an error if the palette is not editable.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The palette name",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_palette ("palette",
"palette",
"The palette",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,
g_param_spec_int ("entry-num",
"entry num",
"The entry to retrieve",
"The entry to get",
G_MININT32, G_MAXINT32, 0,
GIMP_PARAM_READWRITE));
gimp_procedure_add_argument (procedure,

View File

@ -54,30 +54,23 @@ pattern_get_info_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPattern *pattern;
gint width = 0;
gint height = 0;
gint bpp = 0;
name = g_value_get_string (gimp_value_array_index (args, 0));
pattern = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPattern *pattern = gimp_pdb_get_pattern (gimp, name, error);
const Babl *format;
if (pattern)
{
const Babl *format;
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
}
else
success = FALSE;
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -103,38 +96,32 @@ pattern_get_pixels_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpValueArray *return_vals;
const gchar *name;
GimpPattern *pattern;
gint width = 0;
gint height = 0;
gint bpp = 0;
gint num_color_bytes = 0;
guint8 *color_bytes = NULL;
name = g_value_get_string (gimp_value_array_index (args, 0));
pattern = g_value_get_object (gimp_value_array_index (args, 0));
if (success)
{
GimpPattern *pattern = gimp_pdb_get_pattern (gimp, name, error);
if (pattern)
{
const Babl *format;
gpointer data;
const Babl *format;
gpointer data;
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
data = gimp_temp_buf_lock (pattern->mask, format, GEGL_ACCESS_READ);
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
data = gimp_temp_buf_lock (pattern->mask, format, GEGL_ACCESS_READ);
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
num_color_bytes = gimp_temp_buf_get_data_size (pattern->mask);
color_bytes = g_memdup2 (data, num_color_bytes);
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
num_color_bytes = gimp_temp_buf_get_data_size (pattern->mask);
color_bytes = g_memdup2 (data, num_color_bytes);
gimp_temp_buf_unlock (pattern->mask, data);
}
else
success = FALSE;
gimp_temp_buf_unlock (pattern->mask, data);
}
return_vals = gimp_procedure_get_return_values (procedure, success,
@ -152,6 +139,34 @@ pattern_get_pixels_invoker (GimpProcedure *procedure,
return return_vals;
}
static GimpValueArray *
pattern_id_is_valid_invoker (GimpProcedure *procedure,
Gimp *gimp,
GimpContext *context,
GimpProgress *progress,
const GimpValueArray *args,
GError **error)
{
GimpValueArray *return_vals;
const gchar *id;
gboolean valid = FALSE;
id = g_value_get_string (gimp_value_array_index (args, 0));
/* !!! pattern has one fewer args than other resources. */
valid = (gimp_pdb_get_pattern (gimp, id, error) != NULL);
/* When ID is not valid, NULL is returned and error is set.
* Clear error so GIMP not display error dialog.
*/
g_clear_error (error);
return_vals = gimp_procedure_get_return_values (procedure, TRUE, NULL);
g_value_set_boolean (gimp_value_array_index (return_vals, 1), valid);
return return_vals;
}
void
register_pattern_procs (GimpPDB *pdb)
{
@ -164,20 +179,19 @@ register_pattern_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-pattern-get-info");
gimp_procedure_set_static_help (procedure,
"Retrieve information about the specified pattern.",
"This procedure retrieves information about the specified pattern. This includes the pattern extents (width and height).",
"Gets information about the pattern.",
"Gets information about the pattern: the pattern extents (width and height) and bytes per pixel.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The pattern name.",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_pattern ("pattern",
"pattern",
"The pattern",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
g_param_spec_int ("width",
"width",
@ -206,20 +220,19 @@ register_pattern_procs (GimpPDB *pdb)
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-pattern-get-pixels");
gimp_procedure_set_static_help (procedure,
"Retrieve information about the specified pattern (including pixels).",
"This procedure retrieves information about the specified. This includes the pattern extents (width and height), its bpp and its pixel data.",
"Gets information about the pattern (including pixels).",
"Gets information about the pattern: the pattern extents (width and height), its bpp, and its pixel data. The pixel data is an array in C or a list in some languages.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Michael Natterer <mitch@gimp.org>",
"Michael Natterer",
"2004");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("name",
"name",
"The pattern name.",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE));
gimp_param_spec_pattern ("pattern",
"pattern",
"The pattern",
FALSE,
GIMP_PARAM_READWRITE));
gimp_procedure_add_return_value (procedure,
g_param_spec_int ("width",
"width",
@ -251,4 +264,34 @@ register_pattern_procs (GimpPDB *pdb)
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
/*
* gimp-pattern-id-is-valid
*/
procedure = gimp_procedure_new (pattern_id_is_valid_invoker);
gimp_object_set_static_name (GIMP_OBJECT (procedure),
"gimp-pattern-id-is-valid");
gimp_procedure_set_static_help (procedure,
"Whether the ID is a valid reference to installed data.",
"Returns TRUE if this ID is valid.",
NULL);
gimp_procedure_set_static_attribution (procedure,
"Lloyd Konneker",
"Lloyd Konneker",
"2022");
gimp_procedure_add_argument (procedure,
gimp_param_spec_string ("id",
"id",
"The pattern ID",
FALSE, FALSE, TRUE,
NULL,
GIMP_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE));
gimp_procedure_add_return_value (procedure,
g_param_spec_boolean ("valid",
"valid",
"TRUE if the pattern ID is valid",
FALSE,
GIMP_PARAM_READWRITE));
gimp_pdb_register_procedure (pdb, procedure);
g_object_unref (procedure);
}

View File

@ -36,8 +36,17 @@
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
#include "core/gimpselection.h"
/* resource types. */
#include "core/gimpbrush.h"
#include "core/gimpgradient.h"
#include "core/gimppalette.h"
#include "core/gimppattern.h"
#include "text/gimpfont.h"
#include "core/gimpparamspecs.h"
#include "pdb/gimppdb-utils.h"
#include "vectors/gimpvectors.h"
#include "libgimp/gimpgpparams.h"

View File

@ -0,0 +1,235 @@
# API changes in libgimp and the PDB for resources
This explains changes to the GIMP API from v2 to v3,
concerning resources.
The audience is plugin authors, and GIMP developers.
### Resources
A resource is a chunk of data that can be installed with GIMP
and is used by painting tools or for other rendering tasks.
Usually known as brush, font, palette, pattern, gradient and so forth.
### Resources are now first class objects
GimpResource is now a class in libgimp.
It has subclasses:
- Brush
- Font
- Gradient
- Palette
- Pattern
Formerly, the GIMP API had functions operating on resources by name.
Now, there are methods on resource objects.
Methods take an instance of the object as the first argument,
often called "self."
This means that whenever you used a string name to refer to a resource object,
you usually should pass an instance of an object.
### Changes to reference documents
#### libgimp API reference
Shows classes Brush, Font, and so forth.
The classes have instance methods taking the instance as the first argument.
The classes may also have class methods still taking string names.
#### PDB Browser
Remember the PDB Browser shows the C API. You must mentally convert
to the API in bound languages.
Shows some procedures that now take type e.g. GimpBrush
where formerly they took type gcharray i.e. strings.
Shows some procedures that take a string name of a brush.
These are usually class methods.
### New resource objects
FUTURE
Formerly there were no methods in the libgimp API or the PDB for objects:
- Dynamics
- ColorProfile
- ToolPreset
These classes exist primarily so that plugins can let a user choose an instance,
and pass the instance on to other procedures.
### Traits
Informally, resources can have these traits:
- Nameable
- Creatable/Deleable
- Cloneable (Duplicatable)
- Editable
Some resource subclasses don't have all traits.
### ID's and names
The ID and name of a resource are currently the same.
(Some documents and method names may use either word, inconsistently.)
You usually use resource instances instead of their IDs.
This will insulate your code from changes to GIMP re ID versus name.
A plugin should not use a resource's ID.
A plugin should not show the ID/name to a user.
The GIMP app shows the names of resources as a convenience to users,
but usually shows resources visually, that is, iconically.
An ID is opaque, that is, used internally by GIMP.
FUTURE: the ID and name of a resource are distinct.
Different resource instances may have the same name.
Methods returning lists of resources or resource names may return
lists having duplicate names.
### Resource instances are references to underlying data
A resource instance is a proxy, or reference, to the underlying data.
Methods on the instance act on the underlying data.
The underlying data is in GIMP's store of resources.
It is possible for a resource instance to be "invalid"
that is, referring to underlying data that does not exist,
usually when a user uninstalls the thing.
### Creating Resources
Installing a resource is distinct from creating a resource.
GIMP lets you create some resources.
You can't create fonts in GIMP, you can only install them.
For those resources that GIMP lets you create,
the act of creating it also installs it.
For resources that you can create in GIMP:
- some you create using menu items
- some you can create using the API
The API does not let you create a raster brush.
The API does let you create a parametric brush.
For example, in Python:
```
brush = Gimp.Brush.new("Foo")
```
creates a new parametric brush.
Note that the passed name is a proposed name.
If the name is already in use,
the new brush will have a different name.
The brush instance will always be valid.
### Getting Resources by ID
Currently, you usually ask the user to interactively choose a resource.
If you must get a reference to a resource for which you know the ID,
you can new() the resource class and set it's ID property.
See below.
FUTURE Resource classes have get_by_id() methods.
If such a named resource is currently installed,
get_by_id() returns a valid instance of the resource class.
If such a named resource is not currently installed,
the method returns an error.
### Uninitialized or invalid resource instances
You can create an instance of a resource class that is invalid.
For example, in Python:
```
brush = Gimp.Brush()
brush.set_property("id", "Foo")
```
creates an instance that is invalid because there is no underlying data in the GIMP store
(assuming a brush named "Foo" is not installed.)
Ordinarily, you would not use such a construct.
Instead, you should use the new() method
(for resource classes where it is defined)
which creates, installs, and returns a valid instance except in dire circumstances (out of memory.)
### Invalid resource instances due to uninstalls
A plugin may have a resource as a parameter.
An interactive plugin may show a chooser widget to let a user choose a resource.
The user's choices may be saved in settings.
In the same sesssion of GIMP, or in a subsequent session,
a user may invoke the plugin again.
Then the saved settings are displayed in the plugin's dialog
(when the second invocation is also interactive).
When, in the meantime (between invocations of the plugin)
a user has uninstalled the reference resource,
the resource, as a reference, is invalid.
A well-written plugin should handle this case.
Resource classes have:
- is_valid() instance method
- id_is_valid(char * name) class method
Well-written plugins should use these methods to ensure
that saved (deserialized) resource instances
are valid before subsequently using them.
### Naming and renaming
As mentioned above, currently names must be unique.
For some resources, the method rename(char * name) changes the name.
The method fails if the new name is already used.
When the instance is invalid to start with
(it has an ID that does not refer to any installed data)
renaming it can succeed and then it creates a valid instance.
### Duplicating
Duplicating a resource creates and installs the underlying data,
under a new, generated name.
The duplicate() method on an instance returns a new instance.
### Deleting
You can delete some resources. This uninstalls them.
You can delete some brushes, palettes, and gradients,
when they are writeable i.e. editable,
which usually means that a user previously created them.
You can't delete fonts and patterns.
You can delete using the delete() instance method
When you delete a resource, the instance (the proxy in a variable) continues to exist, but is invalid.
### Resource lists
Some functions in GIMP return lists of resource names,
representing the set of resources installed.
For example: gimp_brushes_get_list.
This returns a list of strings, the ID's of the resources.
The list will have no duplicates.
FUTURE: this will return a list of resource instances, and their names may have duplicates.

View File

@ -134,7 +134,8 @@ libgimp_private_sources = \
libgimp_extra_sources = \
gimpenums.c.tail \
gimpgpparams-body.c \
gimpparamspecs-body.c
gimpparamspecs-body.c \
gimpparamspecs-body-resource.c
libgimp_@GIMP_API_VERSION@_la_SOURCES = \
$(libgimp_private_sources) \
@ -329,6 +330,7 @@ Gimp_@GIMP_API_MAJOR_VERSION@_@GIMP_API_MINOR_VERSION@_gir_LIBS = \
Gimp_@GIMP_API_MAJOR_VERSION@_@GIMP_API_MINOR_VERSION@_gir_FILES = \
$(libgimp_introspectable) \
../libgimp/gimpparamspecs-body.c \
../libgimp/gimpparamspecs-body-resource.c \
$(libgimpbase_introspectable) \
$(libgimpcolor_introspectable) \
$(libgimpconfig_introspectable) \

View File

@ -17,6 +17,7 @@ PDB_WRAPPERS_C = \
../libgimp/gimpedit_pdb.c \
../libgimp/gimpfile_pdb.c \
../libgimp/gimpfloatingsel_pdb.c \
../libgimp/gimpfont_pdb.c \
../libgimp/gimpfonts_pdb.c \
../libgimp/gimpfontselect_pdb.c \
../libgimp/gimpgimprc_pdb.c \
@ -68,6 +69,7 @@ PDB_WRAPPERS_H = \
../libgimp/gimpedit_pdb.h \
../libgimp/gimpfile_pdb.h \
../libgimp/gimpfloatingsel_pdb.h \
../libgimp/gimpfont_pdb.h \
../libgimp/gimpfonts_pdb.h \
../libgimp/gimpfontselect_pdb.h \
../libgimp/gimpgimprc_pdb.h \
@ -128,12 +130,15 @@ libgimp_introspectable_headers = \
../libgimp/gimploadprocedure.h \
../libgimp/gimppaletteselect.h \
../libgimp/gimpparamspecs.h \
../libgimp/gimpparamspecs-resource.h \
../libgimp/gimppatternselect.h \
../libgimp/gimppdb.h \
../libgimp/gimpplugin.h \
../libgimp/gimpprocedure.h \
../libgimp/gimpprocedureconfig.h \
../libgimp/gimpprogress.h \
../libgimp/gimpresource.h \
../libgimp/gimpresource-subclass.h \
../libgimp/gimpsaveprocedure.h \
../libgimp/gimpselection.h \
../libgimp/gimptextlayer.h \
@ -171,6 +176,8 @@ libgimp_introspectable = \
../libgimp/gimpprocedure.c \
../libgimp/gimpprocedureconfig.c \
../libgimp/gimpprogress.c \
../libgimp/gimpresource.c \
../libgimp/gimpresource-subclass.c \
../libgimp/gimpsaveprocedure.c \
../libgimp/gimpselection.c \
../libgimp/gimptextlayer.c \
@ -194,6 +201,7 @@ libgimpui_introspectable_headers = \
../libgimp/gimpproceduredialog.h \
../libgimp/gimpprocview.h \
../libgimp/gimpprogressbar.h \
../libgimp/gimppropbrushchooser.h \
../libgimp/gimpsaveproceduredialog.h \
../libgimp/gimpselectbutton.h \
../libgimp/gimpzoompreview.h
@ -214,6 +222,7 @@ libgimpui_introspectable = \
../libgimp/gimpprocbrowserdialog.c \
../libgimp/gimpproceduredialog.c \
../libgimp/gimpprocview.c \
../libgimp/gimppropbrushchooser.c \
../libgimp/gimpsaveproceduredialog.c \
../libgimp/gimpprogressbar.c \
../libgimp/gimpselectbutton.c \

View File

@ -18,8 +18,11 @@ EXPORTS
gimp_brush_get_shape
gimp_brush_get_spacing
gimp_brush_get_spikes
gimp_brush_get_type
gimp_brush_id_is_valid
gimp_brush_is_editable
gimp_brush_is_generated
gimp_brush_is_valid
gimp_brush_new
gimp_brush_rename
gimp_brush_select_destroy
@ -293,6 +296,9 @@ EXPORTS
gimp_floating_sel_attach
gimp_floating_sel_remove
gimp_floating_sel_to_layer
gimp_font_get_type
gimp_font_id_is_valid
gimp_font_is_valid
gimp_font_select_destroy
gimp_font_select_new
gimp_fonts_close_popup
@ -319,8 +325,11 @@ EXPORTS
gimp_gradient_duplicate
gimp_gradient_get_custom_samples
gimp_gradient_get_number_of_segments
gimp_gradient_get_type
gimp_gradient_get_uniform_samples
gimp_gradient_id_is_valid
gimp_gradient_is_editable
gimp_gradient_is_valid
gimp_gradient_new
gimp_gradient_rename
gimp_gradient_segment_get_blending_function
@ -643,10 +652,13 @@ EXPORTS
gimp_palette_entry_get_name
gimp_palette_entry_set_color
gimp_palette_entry_set_name
gimp_palette_get_color_count
gimp_palette_get_colors
gimp_palette_get_columns
gimp_palette_get_info
gimp_palette_get_type
gimp_palette_id_is_valid
gimp_palette_is_editable
gimp_palette_is_valid
gimp_palette_new
gimp_palette_rename
gimp_palette_select_destroy
@ -657,22 +669,32 @@ EXPORTS
gimp_palettes_popup
gimp_palettes_refresh
gimp_palettes_set_popup
gimp_param_brush_get_type
gimp_param_channel_get_type
gimp_param_display_get_type
gimp_param_drawable_get_type
gimp_param_font_get_type
gimp_param_gradient_get_type
gimp_param_image_get_type
gimp_param_item_get_type
gimp_param_layer_get_type
gimp_param_layer_mask_get_type
gimp_param_palette_get_type
gimp_param_pattern_get_type
gimp_param_selection_get_type
gimp_param_spec_brush
gimp_param_spec_channel
gimp_param_spec_display
gimp_param_spec_drawable
gimp_param_spec_font
gimp_param_spec_get_desc
gimp_param_spec_gradient
gimp_param_spec_image
gimp_param_spec_item
gimp_param_spec_layer
gimp_param_spec_layer_mask
gimp_param_spec_palette
gimp_param_spec_pattern
gimp_param_spec_selection
gimp_param_spec_text_layer
gimp_param_spec_vectors
@ -680,6 +702,9 @@ EXPORTS
gimp_param_vectors_get_type
gimp_pattern_get_info
gimp_pattern_get_pixels
gimp_pattern_get_type
gimp_pattern_id_is_valid
gimp_pattern_is_valid
gimp_pattern_select_destroy
gimp_pattern_select_new
gimp_patterns_close_popup
@ -791,6 +816,8 @@ EXPORTS
gimp_progress_uninstall
gimp_progress_update
gimp_quit
gimp_resource_get_id
gimp_resource_get_type
gimp_save_procedure_get_support_comment
gimp_save_procedure_get_support_exif
gimp_save_procedure_get_support_iptc

View File

@ -54,12 +54,15 @@
#include <libgimp/gimploadprocedure.h>
#include <libgimp/gimppaletteselect.h>
#include <libgimp/gimpparamspecs.h>
#include <libgimp/gimpparamspecs-resource.h>
#include <libgimp/gimppatternselect.h>
#include <libgimp/gimppdb.h>
#include <libgimp/gimpplugin.h>
#include <libgimp/gimpprocedureconfig.h>
#include <libgimp/gimpprocedure-params.h>
#include <libgimp/gimpprogress.h>
#include <libgimp/gimpresource.h>
#include <libgimp/gimpresource-subclass.h>
#include <libgimp/gimpsaveprocedure.h>
#include <libgimp/gimpselection.h>
#include <libgimp/gimptextlayer.h>

View File

@ -43,6 +43,7 @@
#include <libgimp/gimpedit_pdb.h>
#include <libgimp/gimpfile_pdb.h>
#include <libgimp/gimpfloatingsel_pdb.h>
#include <libgimp/gimpfont_pdb.h>
#include <libgimp/gimpfonts_pdb.h>
#include <libgimp/gimpfontselect_pdb.h>
#include <libgimp/gimpgimprc_pdb.h>

File diff suppressed because it is too large Load Diff

View File

@ -32,49 +32,61 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gchar* gimp_brush_new (const gchar *name);
gchar* gimp_brush_duplicate (const gchar *name);
gboolean gimp_brush_is_generated (const gchar *name);
gchar* gimp_brush_rename (const gchar *name,
const gchar *new_name);
gboolean gimp_brush_delete (const gchar *name);
gboolean gimp_brush_is_editable (const gchar *name);
gboolean gimp_brush_get_info (const gchar *name,
gint *width,
gint *height,
gint *mask_bpp,
gint *color_bpp);
gboolean gimp_brush_get_pixels (const gchar *name,
gint *width,
gint *height,
gint *mask_bpp,
gint *num_mask_bytes,
guint8 **mask_bytes,
gint *color_bpp,
gint *num_color_bytes,
guint8 **color_bytes);
gboolean gimp_brush_get_spacing (const gchar *name,
gint *spacing);
gboolean gimp_brush_set_spacing (const gchar *name,
gint spacing);
GimpBrushGeneratedShape gimp_brush_get_shape (const gchar *name);
GimpBrushGeneratedShape gimp_brush_set_shape (const gchar *name,
GimpBrushGeneratedShape shape_in);
gdouble gimp_brush_get_radius (const gchar *name);
gdouble gimp_brush_set_radius (const gchar *name,
gdouble radius_in);
gint gimp_brush_get_spikes (const gchar *name);
gint gimp_brush_set_spikes (const gchar *name,
gint spikes_in);
gdouble gimp_brush_get_hardness (const gchar *name);
gdouble gimp_brush_set_hardness (const gchar *name,
gdouble hardness_in);
gdouble gimp_brush_get_aspect_ratio (const gchar *name);
gdouble gimp_brush_set_aspect_ratio (const gchar *name,
gdouble aspect_ratio_in);
gdouble gimp_brush_get_angle (const gchar *name);
gdouble gimp_brush_set_angle (const gchar *name,
gdouble angle_in);
GimpBrush* gimp_brush_new (const gchar *name);
GimpBrush* gimp_brush_duplicate (GimpBrush *brush);
gboolean gimp_brush_is_generated (GimpBrush *brush);
gboolean gimp_brush_id_is_valid (const gchar *id);
GimpBrush* gimp_brush_rename (GimpBrush *brush,
const gchar *new_name);
gboolean gimp_brush_delete (GimpBrush *brush);
gboolean gimp_brush_is_editable (GimpBrush *brush);
gboolean gimp_brush_get_info (GimpBrush *brush,
gint *width,
gint *height,
gint *mask_bpp,
gint *color_bpp);
gboolean gimp_brush_get_pixels (GimpBrush *brush,
gint *width,
gint *height,
gint *mask_bpp,
gint *num_mask_bytes,
guint8 **mask_bytes,
gint *color_bpp,
gint *num_color_bytes,
guint8 **color_bytes);
gint gimp_brush_get_spacing (GimpBrush *brush);
gboolean gimp_brush_set_spacing (GimpBrush *brush,
gint spacing);
gboolean gimp_brush_get_shape (GimpBrush *brush,
GimpBrushGeneratedShape *shape);
gboolean gimp_brush_set_shape (GimpBrush *brush,
GimpBrushGeneratedShape shape_in,
GimpBrushGeneratedShape *shape_out);
gboolean gimp_brush_get_radius (GimpBrush *brush,
gdouble *radius);
gboolean gimp_brush_set_radius (GimpBrush *brush,
gdouble radius_in,
gdouble *radius_out);
gboolean gimp_brush_get_spikes (GimpBrush *brush,
gint *spikes);
gboolean gimp_brush_set_spikes (GimpBrush *brush,
gint spikes_in,
gint *spikes_out);
gboolean gimp_brush_get_hardness (GimpBrush *brush,
gdouble *hardness);
gboolean gimp_brush_set_hardness (GimpBrush *brush,
gdouble hardness_in,
gdouble *hardness_out);
gboolean gimp_brush_get_aspect_ratio (GimpBrush *brush,
gdouble *aspect_ratio);
gboolean gimp_brush_set_aspect_ratio (GimpBrush *brush,
gdouble aspect_ratio_in,
gdouble *aspect_ratio_out);
gboolean gimp_brush_get_angle (GimpBrush *brush,
gdouble *angle);
gboolean gimp_brush_set_angle (GimpBrush *brush,
gdouble angle_in,
gdouble *angle_out);
G_END_DECLS

View File

@ -443,7 +443,16 @@ gimp_brush_select_button_set_brush (GimpBrushSelectButton *button,
opacity = gimp_context_get_opacity ();
if (spacing == -1)
gimp_brush_get_spacing (name, &spacing);
{
/* GimpBrush now a class. get_spacing is now an instance method.
* FIXME: when this widget takes a brush instance instead of a name,
* the next two lines should be deleted.
*/
GimpBrush *brush = g_object_new (GIMP_TYPE_BRUSH, NULL);
g_object_set (brush, "id", name, NULL);
spacing = gimp_brush_get_spacing (brush);
}
if (paint_mode == -1)
paint_mode = gimp_context_get_paint_mode ();

File diff suppressed because it is too large Load Diff

View File

@ -66,8 +66,8 @@ gboolean gimp_context_get_line_dash_pattern (gint
gdouble **dashes);
gboolean gimp_context_set_line_dash_pattern (gint num_dashes,
const gdouble *dashes);
gchar* gimp_context_get_brush (void);
gboolean gimp_context_set_brush (const gchar *name);
GimpBrush* gimp_context_get_brush (void);
gboolean gimp_context_set_brush (GimpBrush *brush);
gdouble gimp_context_get_brush_size (void);
gboolean gimp_context_set_brush_size (gdouble size);
gboolean gimp_context_set_brush_default_size (void);
@ -89,10 +89,10 @@ gboolean gimp_context_are_dynamics_enabled (void);
gboolean gimp_context_enable_dynamics (gboolean enable);
gchar* gimp_context_get_mypaint_brush (void);
gboolean gimp_context_set_mypaint_brush (const gchar *name);
gchar* gimp_context_get_pattern (void);
gboolean gimp_context_set_pattern (const gchar *name);
gchar* gimp_context_get_gradient (void);
gboolean gimp_context_set_gradient (const gchar *name);
GimpPattern* gimp_context_get_pattern (void);
gboolean gimp_context_set_pattern (GimpPattern *pattern);
GimpGradient* gimp_context_get_gradient (void);
gboolean gimp_context_set_gradient (GimpGradient *gradient);
gboolean gimp_context_set_gradient_fg_bg_rgb (void);
gboolean gimp_context_set_gradient_fg_bg_hsv_cw (void);
gboolean gimp_context_set_gradient_fg_bg_hsv_ccw (void);
@ -103,10 +103,10 @@ GimpRepeatMode gimp_context_get_gradient_repeat_mode (void);
gboolean gimp_context_set_gradient_repeat_mode (GimpRepeatMode repeat_mode);
gboolean gimp_context_get_gradient_reverse (void);
gboolean gimp_context_set_gradient_reverse (gboolean reverse);
gchar* gimp_context_get_palette (void);
gboolean gimp_context_set_palette (const gchar *name);
gchar* gimp_context_get_font (void);
gboolean gimp_context_set_font (const gchar *name);
GimpPalette* gimp_context_get_palette (void);
gboolean gimp_context_set_palette (GimpPalette *palette);
GimpFont* gimp_context_get_font (void);
gboolean gimp_context_set_font (GimpFont *font);
gboolean gimp_context_get_antialias (void);
gboolean gimp_context_set_antialias (gboolean antialias);
gboolean gimp_context_get_feather (void);

73
libgimp/gimpfont_pdb.c Normal file
View File

@ -0,0 +1,73 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
*
* gimpfont_pdb.c
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/* NOTE: This file is auto-generated by pdbgen.pl */
#include "config.h"
#include "stamp-pdbgen.h"
#include "gimp.h"
/**
* SECTION: gimpfont
* @title: gimpfont
* @short_description: Installable object used by text tools.
*
* Installable object used by text tools.
**/
/**
* gimp_font_id_is_valid:
* @id: The font ID.
*
* Whether the ID is a valid reference to installed data.
*
* Returns TRUE if this ID is valid.
*
* Returns: TRUE if the font ID is valid.
*
* Since: 3.0
**/
gboolean
gimp_font_id_is_valid (const gchar *id)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean valid = FALSE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, id,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-font-id-is-valid",
args);
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
valid = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
gimp_value_array_unref (return_vals);
return valid;
}

40
libgimp/gimpfont_pdb.h Normal file
View File

@ -0,0 +1,40 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
*
* gimpfont_pdb.h
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/* NOTE: This file is auto-generated by pdbgen.pl */
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimp.h> can be included directly."
#endif
#ifndef __GIMP_FONT_PDB_H__
#define __GIMP_FONT_PDB_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gboolean gimp_font_id_is_valid (const gchar *id);
G_END_DECLS
#endif /* __GIMP_FONT_PDB_H__ */

View File

@ -195,6 +195,23 @@ _gimp_gp_param_def_to_param_spec (const GPParamDef *param_def)
return gimp_param_spec_vectors (name, nick, blurb,
param_def->meta.m_id.none_ok,
flags);
/* Resources */
if (! strcmp (param_def->type_name, "GimpParamBrush"))
return gimp_param_spec_brush (name, nick, blurb,
param_def->meta.m_id.none_ok, flags);
if (! strcmp (param_def->type_name, "GimpParamFont"))
return gimp_param_spec_font (name, nick, blurb,
param_def->meta.m_id.none_ok, flags);
if (! strcmp (param_def->type_name, "GimpParamGradient"))
return gimp_param_spec_gradient (name, nick, blurb,
param_def->meta.m_id.none_ok, flags);
if (! strcmp (param_def->type_name, "GimpParamPalette"))
return gimp_param_spec_palette (name, nick, blurb,
param_def->meta.m_id.none_ok, flags);
if (! strcmp (param_def->type_name, "GimpParamPattern"))
return gimp_param_spec_pattern (name, nick, blurb,
param_def->meta.m_id.none_ok, flags);
break;
case GP_PARAM_DEF_TYPE_ID_ARRAY:
@ -205,8 +222,7 @@ _gimp_gp_param_def_to_param_spec (const GPParamDef *param_def)
break;
}
g_printerr ("%s: GParamSpec type '%s' is not handled\n",
G_STRFUNC, param_def->type_name);
g_warning ("%s: GParamSpec type unsupported '%s'", G_STRFUNC, param_def->type_name);
return NULL;
}
@ -336,6 +352,47 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID;
param_def->meta.m_id.none_ok = ispec->none_ok;
}
/* Resources. */
else if (GIMP_IS_PARAM_SPEC_BRUSH (pspec))
{
GimpParamSpecBrush *ispec = GIMP_PARAM_SPEC_BRUSH (pspec);
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID;
param_def->meta.m_id.none_ok = ispec->none_ok;
}
else if (GIMP_IS_PARAM_SPEC_FONT (pspec))
{
GimpParamSpecFont *ispec = GIMP_PARAM_SPEC_FONT (pspec);
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID;
param_def->meta.m_id.none_ok = ispec->none_ok;
}
else if (GIMP_IS_PARAM_SPEC_GRADIENT (pspec))
{
GimpParamSpecGradient *ispec = GIMP_PARAM_SPEC_GRADIENT (pspec);
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID;
param_def->meta.m_id.none_ok = ispec->none_ok;
}
else if (GIMP_IS_PARAM_SPEC_PALETTE (pspec))
{
GimpParamSpecPalette *ispec = GIMP_PARAM_SPEC_PALETTE (pspec);
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID;
param_def->meta.m_id.none_ok = ispec->none_ok;
}
else if (GIMP_IS_PARAM_SPEC_PATTERN (pspec))
{
GimpParamSpecPattern *ispec = GIMP_PARAM_SPEC_PATTERN (pspec);
param_def->param_def_type = GP_PARAM_DEF_TYPE_ID;
param_def->meta.m_id.none_ok = ispec->none_ok;
}
else if (GIMP_IS_PARAM_SPEC_OBJECT_ARRAY (pspec))
@ -388,6 +445,26 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
{
type_name = "GimpParamVectors";
}
else if (value_type == GIMP_TYPE_BRUSH)
{
type_name = "GimpParamBrush";
}
else if (value_type == GIMP_TYPE_FONT)
{
type_name = "GimpParamFont";
}
else if (value_type == GIMP_TYPE_GRADIENT)
{
type_name = "GimpParamGradient";
}
else if (value_type == GIMP_TYPE_PALETTE)
{
type_name = "GimpParamPalette";
}
else if (value_type == GIMP_TYPE_PATTERN)
{
type_name = "GimpParamPattern";
}
if (type_name)
{
@ -397,8 +474,8 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
}
else
{
g_printerr ("%s: GParamSpecObject for unsupported object type '%s'\n",
G_STRFUNC, param_def->type_name);
g_warning ("%s: GParamSpecObject for unsupported type '%s:%s'",
G_STRFUNC, param_def->type_name, param_def->value_type_name);
}
}
}
@ -436,6 +513,88 @@ get_display_by_id (gpointer gimp,
#endif
}
/* Return an object instance by ID, for a subclass of GimpResource
*
* On app/core side, returns existing instance.
* (But GimpResource is not defined app/core)
*
* On libgimp side, creates a new instance of a proxy.
* The new instance is put in a GValue.
* The new instance's life is the same as the GValue.
* The GValue should eventually be freed by the caller,
* but not while the resource proxy instance is in use.
*/
static GObject *
get_resource_by_id (gpointer gimp,
GType gtype,
gchar *id)
{
#ifdef LIBGIMP_COMPILATION
/* Return a new proxy instance, not any instance already existing.
* Primarily for class's new() and duplicate() methods,
* and for procedure args of a resource type.
*/
GObject *resource = g_object_new (gtype, NULL);
g_object_set (resource, "id", id, NULL);
g_debug ("libgimp:get_resource_by_id");
return resource;
#else
GError *error = NULL;
GObject *resource = NULL;
if (gtype == GIMP_TYPE_BRUSH)
resource = (GObject*) gimp_pdb_get_brush (gimp, id, GIMP_PDB_DATA_ACCESS_READ, &error);
else if (gtype == GIMP_TYPE_FONT)
resource = (GObject*) gimp_pdb_get_font (gimp, id, &error);
else if (gtype == GIMP_TYPE_GRADIENT)
resource = (GObject*) gimp_pdb_get_gradient (gimp, id, GIMP_PDB_DATA_ACCESS_READ, &error);
else if (gtype == GIMP_TYPE_PALETTE)
resource = (GObject*) gimp_pdb_get_palette (gimp, id, GIMP_PDB_DATA_ACCESS_READ, &error);
else if (gtype == GIMP_TYPE_PATTERN)
resource = (GObject*) gimp_pdb_get_pattern (gimp, id, &error);
else
g_warning ("%s unsupported type: %s", G_STRFUNC, g_type_name (gtype));
if (error != NULL)
g_warning ("A plugin is trying to use a resource %s that is no longer installed.", g_type_name (gtype) );
return resource;
#endif
}
/* Return a resource's ID.
* This hides the fact that app/core uses object name as ID, and doesn't have a GimpResource class.
*
* On app/core side, object name. GimpResource is not a class.
*
* On libgimp side, returns the id property. Class GimpResource is defined.
*/
static gchar *
get_resource_id (GObject *resource)
{
#ifdef LIBGIMP_COMPILATION
gchar *id = NULL;
/* Require resource is-a GimpResource having property id. */
g_debug ("libgimp: %s", G_STRFUNC);
g_object_get (resource, "id", &id, NULL);
return id;
#else
/* Cast to avoid "discarding const qualifier" */
return (gchar*) gimp_object_get_name (resource);
#endif
}
/* Deserialize a gp_param (from the wire) to an instance of object or primitive type.
* This is used on both the core and plugin (libgimp) side,
* each having its own class definitions for a same named class.
* Thus this creates different objects, depending on which side it is.
* See the conditionally compiled constructors/fetchers above.
*/
static void
gimp_gp_param_to_value (gpointer gimp,
const GPParam *param,
@ -569,6 +728,10 @@ gimp_gp_param_to_value (gpointer gimp,
{
g_value_set_object (value, get_display_by_id (gimp, param->data.d_int));
}
else if (GIMP_VALUE_HOLDS_RESOURCE (value))
{
g_value_set_object (value, get_resource_by_id (gimp, G_VALUE_TYPE (value), param->data.d_string));
}
else if (G_VALUE_HOLDS_PARAM (value))
{
GParamSpec *pspec =
@ -576,6 +739,11 @@ gimp_gp_param_to_value (gpointer gimp,
g_value_take_param (value, pspec);
}
else
{
g_warning ("%s: unsupported deserialization to GValue of type '%s'\n",
G_STRFUNC, param->type_name);
}
}
GimpValueArray *
@ -882,6 +1050,14 @@ gimp_value_to_gp_param (const GValue *value,
param->data.d_int = display ? gimp_display_get_id (display) : -1;
}
else if (GIMP_VALUE_HOLDS_RESOURCE (value))
{
GObject *resource = g_value_get_object (value);
param->param_type = GP_PARAM_TYPE_STRING;
param->data.d_string = resource ? get_resource_id (resource) : "";
}
else if (G_VALUE_HOLDS_PARAM (value))
{
param->param_type = GP_PARAM_TYPE_PARAM_DEF;
@ -891,8 +1067,7 @@ gimp_value_to_gp_param (const GValue *value,
}
if (param->param_type == -1)
g_printerr ("%s: GValue contains unsupported type '%s'\n",
G_STRFUNC, param->type_name);
g_warning ("%s: GValue holds unsupported type '%s'", G_STRFUNC, param->type_name);
}
GPParam *

File diff suppressed because it is too large Load Diff

View File

@ -32,106 +32,107 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gchar* gimp_gradient_new (const gchar *name);
gchar* gimp_gradient_duplicate (const gchar *name);
gboolean gimp_gradient_is_editable (const gchar *name);
gchar* gimp_gradient_rename (const gchar *name,
const gchar *new_name);
gboolean gimp_gradient_delete (const gchar *name);
gint gimp_gradient_get_number_of_segments (const gchar *name);
gboolean gimp_gradient_get_uniform_samples (const gchar *name,
gint num_samples,
gboolean reverse,
gint *num_color_samples,
gdouble **color_samples);
gboolean gimp_gradient_get_custom_samples (const gchar *name,
gint num_samples,
const gdouble *positions,
gboolean reverse,
gint *num_color_samples,
gdouble **color_samples);
gboolean gimp_gradient_segment_get_left_color (const gchar *name,
gint segment,
GimpRGB *color,
gdouble *opacity);
gboolean gimp_gradient_segment_set_left_color (const gchar *name,
gint segment,
const GimpRGB *color,
gdouble opacity);
gboolean gimp_gradient_segment_get_right_color (const gchar *name,
gint segment,
GimpRGB *color,
gdouble *opacity);
gboolean gimp_gradient_segment_set_right_color (const gchar *name,
gint segment,
const GimpRGB *color,
gdouble opacity);
gboolean gimp_gradient_segment_get_left_pos (const gchar *name,
gint segment,
gdouble *pos);
gboolean gimp_gradient_segment_set_left_pos (const gchar *name,
gint segment,
gdouble pos,
gdouble *final_pos);
gboolean gimp_gradient_segment_get_middle_pos (const gchar *name,
gint segment,
gdouble *pos);
gboolean gimp_gradient_segment_set_middle_pos (const gchar *name,
gint segment,
gdouble pos,
gdouble *final_pos);
gboolean gimp_gradient_segment_get_right_pos (const gchar *name,
gint segment,
gdouble *pos);
gboolean gimp_gradient_segment_set_right_pos (const gchar *name,
gint segment,
gdouble pos,
gdouble *final_pos);
gboolean gimp_gradient_segment_get_blending_function (const gchar *name,
gint segment,
GimpGradientSegmentType *blend_func);
gboolean gimp_gradient_segment_get_coloring_type (const gchar *name,
gint segment,
GimpGradientSegmentColor *coloring_type);
gboolean gimp_gradient_segment_range_set_blending_function (const gchar *name,
gint start_segment,
gint end_segment,
GimpGradientSegmentType blending_function);
gboolean gimp_gradient_segment_range_set_coloring_type (const gchar *name,
gint start_segment,
gint end_segment,
GimpGradientSegmentColor coloring_type);
gboolean gimp_gradient_segment_range_flip (const gchar *name,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_replicate (const gchar *name,
gint start_segment,
gint end_segment,
gint replicate_times);
gboolean gimp_gradient_segment_range_split_midpoint (const gchar *name,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_split_uniform (const gchar *name,
gint start_segment,
gint end_segment,
gint split_parts);
gboolean gimp_gradient_segment_range_delete (const gchar *name,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_redistribute_handles (const gchar *name,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_blend_colors (const gchar *name,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_blend_opacity (const gchar *name,
gint start_segment,
gint end_segment);
gdouble gimp_gradient_segment_range_move (const gchar *name,
gint start_segment,
gint end_segment,
gdouble delta,
gboolean control_compress);
GimpGradient* gimp_gradient_new (const gchar *name);
GimpGradient* gimp_gradient_duplicate (GimpGradient *gradient);
gboolean gimp_gradient_is_editable (GimpGradient *gradient);
GimpGradient* gimp_gradient_rename (GimpGradient *gradient,
const gchar *new_name);
gboolean gimp_gradient_delete (GimpGradient *gradient);
gint gimp_gradient_get_number_of_segments (GimpGradient *gradient);
gboolean gimp_gradient_get_uniform_samples (GimpGradient *gradient,
gint num_samples,
gboolean reverse,
gint *num_color_samples,
gdouble **color_samples);
gboolean gimp_gradient_get_custom_samples (GimpGradient *gradient,
gint num_samples,
const gdouble *positions,
gboolean reverse,
gint *num_color_samples,
gdouble **color_samples);
gboolean gimp_gradient_id_is_valid (const gchar *id);
gboolean gimp_gradient_segment_get_left_color (GimpGradient *gradient,
gint segment,
GimpRGB *color,
gdouble *opacity);
gboolean gimp_gradient_segment_set_left_color (GimpGradient *gradient,
gint segment,
const GimpRGB *color,
gdouble opacity);
gboolean gimp_gradient_segment_get_right_color (GimpGradient *gradient,
gint segment,
GimpRGB *color,
gdouble *opacity);
gboolean gimp_gradient_segment_set_right_color (GimpGradient *gradient,
gint segment,
const GimpRGB *color,
gdouble opacity);
gboolean gimp_gradient_segment_get_left_pos (GimpGradient *gradient,
gint segment,
gdouble *pos);
gboolean gimp_gradient_segment_set_left_pos (GimpGradient *gradient,
gint segment,
gdouble pos,
gdouble *final_pos);
gboolean gimp_gradient_segment_get_middle_pos (GimpGradient *gradient,
gint segment,
gdouble *pos);
gboolean gimp_gradient_segment_set_middle_pos (GimpGradient *gradient,
gint segment,
gdouble pos,
gdouble *final_pos);
gboolean gimp_gradient_segment_get_right_pos (GimpGradient *gradient,
gint segment,
gdouble *pos);
gboolean gimp_gradient_segment_set_right_pos (GimpGradient *gradient,
gint segment,
gdouble pos,
gdouble *final_pos);
gboolean gimp_gradient_segment_get_blending_function (GimpGradient *gradient,
gint segment,
GimpGradientSegmentType *blend_func);
gboolean gimp_gradient_segment_get_coloring_type (GimpGradient *gradient,
gint segment,
GimpGradientSegmentColor *coloring_type);
gboolean gimp_gradient_segment_range_set_blending_function (GimpGradient *gradient,
gint start_segment,
gint end_segment,
GimpGradientSegmentType blending_function);
gboolean gimp_gradient_segment_range_set_coloring_type (GimpGradient *gradient,
gint start_segment,
gint end_segment,
GimpGradientSegmentColor coloring_type);
gboolean gimp_gradient_segment_range_flip (GimpGradient *gradient,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_replicate (GimpGradient *gradient,
gint start_segment,
gint end_segment,
gint replicate_times);
gboolean gimp_gradient_segment_range_split_midpoint (GimpGradient *gradient,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_split_uniform (GimpGradient *gradient,
gint start_segment,
gint end_segment,
gint split_parts);
gboolean gimp_gradient_segment_range_delete (GimpGradient *gradient,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_redistribute_handles (GimpGradient *gradient,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_blend_colors (GimpGradient *gradient,
gint start_segment,
gint end_segment);
gboolean gimp_gradient_segment_range_blend_opacity (GimpGradient *gradient,
gint start_segment,
gint end_segment);
gdouble gimp_gradient_segment_range_move (GimpGradient *gradient,
gint start_segment,
gint end_segment,
gdouble delta,
gboolean control_compress);
G_END_DECLS

View File

@ -30,9 +30,9 @@
/**
* SECTION: gimppalette
* @title: gimppalette
* @short_description: Functions operating on a single palette.
* @short_description: Installable object, a small set of colors a user can choose from.
*
* Functions operating on a single palette.
* Installable object, a small set of colors a user can choose from.
**/
@ -42,19 +42,21 @@
*
* Creates a new palette
*
* This procedure creates a new, uninitialized palette
* Creates a new palette. The new palette has no color entries. You
* must add color entries for a user to choose. The actual name might
* be different than the requested name, when the requested name is
* already in use.
*
* Returns: (transfer full): The actual new palette name.
* The returned value must be freed with g_free().
* Returns: (transfer full): The palette.
*
* Since: 2.2
**/
gchar *
GimpPalette *
gimp_palette_new (const gchar *name)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gchar *actual_name = NULL;
GimpPalette *palette = NULL;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
@ -66,35 +68,34 @@ gimp_palette_new (const gchar *name)
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
actual_name = GIMP_VALUES_DUP_STRING (return_vals, 1);
palette = GIMP_VALUES_GET_PALETTE (return_vals, 1);
gimp_value_array_unref (return_vals);
return actual_name;
return palette;
}
/**
* gimp_palette_duplicate:
* @name: The palette name.
* @palette: The palette.
*
* Duplicates a palette
*
* This procedure creates an identical palette by a different name
* Returns a copy having a different, unique ID.
*
* Returns: (transfer full): The name of the palette's copy.
* The returned value must be freed with g_free().
* Returns: (transfer full): A copy of the palette.
*
* Since: 2.2
**/
gchar *
gimp_palette_duplicate (const gchar *name)
GimpPalette *
gimp_palette_duplicate (GimpPalette *palette)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gchar *copy_name = NULL;
GimpPalette *palette_copy = NULL;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -103,37 +104,78 @@ gimp_palette_duplicate (const gchar *name)
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
copy_name = GIMP_VALUES_DUP_STRING (return_vals, 1);
palette_copy = GIMP_VALUES_GET_PALETTE (return_vals, 1);
gimp_value_array_unref (return_vals);
return copy_name;
return palette_copy;
}
/**
* gimp_palette_id_is_valid:
* @id: The palette ID.
*
* Whether the ID is a valid reference to installed data.
*
* Returns TRUE if this ID is valid.
*
* Returns: TRUE if the palette ID is valid.
*
* Since: 3.0
**/
gboolean
gimp_palette_id_is_valid (const gchar *id)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean valid = FALSE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, id,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-palette-id-is-valid",
args);
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
valid = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
gimp_value_array_unref (return_vals);
return valid;
}
/**
* gimp_palette_rename:
* @name: The palette name.
* @new_name: The new name of the palette.
* @palette: The palette.
* @new_name: The requested new name of the palette.
*
* Rename a palette
*
* This procedure renames a palette
* Renames a palette. The name is the same as the ID. When the proposed
* name is already used, GIMP generates a unique name, which get_id()
* will return.
* Returns a reference to a renamed palette, which you should assign to
* the original var or a differently named var. Any existing references
* will be invalid. Resources in plugins are proxies holding an ID,
* which can be invalid when the resource is renamed.
*
* Returns: (transfer full): The actual new name of the palette.
* The returned value must be freed with g_free().
* Returns: (transfer full): A reference to the renamed palette.
*
* Since: 2.2
**/
gchar *
gimp_palette_rename (const gchar *name,
GimpPalette *
gimp_palette_rename (GimpPalette *palette,
const gchar *new_name)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gchar *actual_name = NULL;
GimpPalette *palette_renamed = NULL;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_STRING, new_name,
G_TYPE_NONE);
@ -143,34 +185,36 @@ gimp_palette_rename (const gchar *name,
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
actual_name = GIMP_VALUES_DUP_STRING (return_vals, 1);
palette_renamed = GIMP_VALUES_GET_PALETTE (return_vals, 1);
gimp_value_array_unref (return_vals);
return actual_name;
return palette_renamed;
}
/**
* gimp_palette_delete:
* @name: The palette name.
* @palette: The palette.
*
* Deletes a palette
*
* This procedure deletes a palette
* Deletes a palette. Returns an error if the palette is not deletable.
* Deletes the palette's data. You should not use the palette
* afterwards.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_delete (const gchar *name)
gimp_palette_delete (GimpPalette *palette)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -187,9 +231,9 @@ gimp_palette_delete (const gchar *name)
/**
* gimp_palette_is_editable:
* @name: The palette name.
* @palette: The palette.
*
* Tests if palette can be edited
* Whether the palette can be edited
*
* Returns TRUE if you have permission to change the palette
*
@ -198,14 +242,14 @@ gimp_palette_delete (const gchar *name)
* Since: 2.4
**/
gboolean
gimp_palette_is_editable (const gchar *name)
gimp_palette_is_editable (GimpPalette *palette)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean editable = FALSE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -222,56 +266,49 @@ gimp_palette_is_editable (const gchar *name)
}
/**
* gimp_palette_get_info:
* @name: The palette name.
* @num_colors: (out): The number of colors in the palette.
* gimp_palette_get_color_count:
* @palette: The palette.
*
* Retrieve information about the specified palette.
* Get the count of colors in the palette.
*
* This procedure retrieves information about the specified palette.
* This includes the name, and the number of colors.
* Returns the number of colors in the palette.
*
* Returns: TRUE on success.
* Returns: The number of colors in the palette.
*
* Since: 2.2
**/
gboolean
gimp_palette_get_info (const gchar *name,
gint *num_colors)
gint
gimp_palette_get_color_count (GimpPalette *palette)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
gint num_colors = 0;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-palette-get-info",
"gimp-palette-get-color-count",
args);
gimp_value_array_unref (args);
*num_colors = 0;
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
if (success)
*num_colors = GIMP_VALUES_GET_INT (return_vals, 1);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
num_colors = GIMP_VALUES_GET_INT (return_vals, 1);
gimp_value_array_unref (return_vals);
return success;
return num_colors;
}
/**
* gimp_palette_get_colors:
* @name: The palette name.
* @palette: The palette.
* @num_colors: (out): Length of the colors array.
*
* Gets all colors from the specified palette.
* Gets colors in the palette.
*
* This procedure retrieves all color entries of the specified palette.
* Returns an array of colors in the palette.
*
* Returns: (array length=num_colors) (element-type GimpRGB) (transfer full):
* The colors in the palette.
@ -280,7 +317,7 @@ gimp_palette_get_info (const gchar *name,
* Since: 2.6
**/
GimpRGB *
gimp_palette_get_colors (const gchar *name,
gimp_palette_get_colors (GimpPalette *palette,
gint *num_colors)
{
GimpValueArray *args;
@ -288,7 +325,7 @@ gimp_palette_get_colors (const gchar *name,
GimpRGB *colors = NULL;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -311,26 +348,25 @@ gimp_palette_get_colors (const gchar *name,
/**
* gimp_palette_get_columns:
* @name: The palette name.
* @palette: The palette.
*
* Retrieves the number of columns to use to display this palette
* Gets the number of columns used to display the palette
*
* This procedures retrieves the preferred number of columns to use
* when the palette is being displayed.
* Gets the preferred number of columns to display the palette.
*
* Returns: The number of columns used to display this palette.
*
* Since: 2.4
**/
gint
gimp_palette_get_columns (const gchar *name)
gimp_palette_get_columns (GimpPalette *palette)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gint num_columns = 0;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -348,21 +384,21 @@ gimp_palette_get_columns (const gchar *name)
/**
* gimp_palette_set_columns:
* @name: The palette name.
* @palette: The palette.
* @columns: The new number of columns.
*
* Sets the number of columns to use when displaying the palette
* Sets the number of columns used to display the palette
*
* This procedures controls how many colors are shown per row when the
* palette is being displayed. This value can only be changed if the
* palette is writable. The maximum allowed value is 64.
* Set the number of colors shown per row when the palette is
* displayed. Returns an error when the palette is not editable. The
* maximum allowed value is 64.
*
* Returns: TRUE on success.
*
* Since: 2.4
**/
gboolean
gimp_palette_set_columns (const gchar *name,
gimp_palette_set_columns (GimpPalette *palette,
gint columns)
{
GimpValueArray *args;
@ -370,7 +406,7 @@ gimp_palette_set_columns (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_INT, columns,
G_TYPE_NONE);
@ -388,22 +424,24 @@ gimp_palette_set_columns (const gchar *name,
/**
* gimp_palette_add_entry:
* @name: The palette name.
* @entry_name: The name of the entry.
* @color: The new entry's color color.
* @palette: The palette.
* @entry_name: A name for the entry.
* @color: The color for the added entry.
* @entry_num: (out): The index of the added entry.
*
* Adds a palette entry to the specified palette.
* Appends an entry to the palette.
*
* This procedure adds an entry to the specified palette. It returns an
* error if the entry palette does not exist.
* Appends an entry to the palette. Neither color nor name must be
* unique within the palette. When name is the empty string, this sets
* the entry name to \"Untitled\". Returns the index of the entry.
* Returns an error when palette is not editable.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_add_entry (const gchar *name,
gimp_palette_add_entry (GimpPalette *palette,
const gchar *entry_name,
const GimpRGB *color,
gint *entry_num)
@ -413,7 +451,7 @@ gimp_palette_add_entry (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_STRING, entry_name,
GIMP_TYPE_RGB, color,
G_TYPE_NONE);
@ -437,20 +475,20 @@ gimp_palette_add_entry (const gchar *name,
/**
* gimp_palette_delete_entry:
* @name: The palette name.
* @entry_num: The index of the added entry.
* @palette: The palette.
* @entry_num: The index of the entry to delete.
*
* Deletes a palette entry from the specified palette.
* Deletes an entry from the palette.
*
* This procedure deletes an entry from the specified palette. It
* returns an error if the entry palette does not exist.
* Deletes an entry from the palette. Returns an error if the index is
* out or range. Returns an error if the palette is not editable.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_delete_entry (const gchar *name,
gimp_palette_delete_entry (GimpPalette *palette,
gint entry_num)
{
GimpValueArray *args;
@ -458,7 +496,7 @@ gimp_palette_delete_entry (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_INT, entry_num,
G_TYPE_NONE);
@ -476,22 +514,21 @@ gimp_palette_delete_entry (const gchar *name,
/**
* gimp_palette_entry_get_color:
* @name: The palette name.
* @entry_num: The entry to retrieve.
* @color: (out caller-allocates): The color requested.
* @palette: The palette.
* @entry_num: The index of the entry to get the color of.
* @color: (out caller-allocates): The color at the index.
*
* Gets the specified palette entry from the specified palette.
* Gets the color of an entry in the palette.
*
* This procedure retrieves the color of the zero-based entry specified
* for the specified palette. It returns an error if the entry does not
* exist.
* Returns the color of the entry at the given zero-based index into
* the palette. Returns an error when the index is out of range.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_entry_get_color (const gchar *name,
gimp_palette_entry_get_color (GimpPalette *palette,
gint entry_num,
GimpRGB *color)
{
@ -500,7 +537,7 @@ gimp_palette_entry_get_color (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_INT, entry_num,
G_TYPE_NONE);
@ -521,22 +558,22 @@ gimp_palette_entry_get_color (const gchar *name,
/**
* gimp_palette_entry_set_color:
* @name: The palette name.
* @entry_num: The entry to retrieve.
* @palette: The palette.
* @entry_num: The entry to get.
* @color: The new color.
*
* Sets the specified palette entry in the specified palette.
* Sets the color of an entry in the palette.
*
* This procedure sets the color of the zero-based entry specified for
* the specified palette. It returns an error if the entry does not
* exist.
* Sets the color of the entry at the zero-based index into the
* palette. Returns an error when the index is out of range. Returns an
* error when the palette is not editable.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_entry_set_color (const gchar *name,
gimp_palette_entry_set_color (GimpPalette *palette,
gint entry_num,
const GimpRGB *color)
{
@ -545,7 +582,7 @@ gimp_palette_entry_set_color (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_INT, entry_num,
GIMP_TYPE_RGB, color,
G_TYPE_NONE);
@ -564,22 +601,21 @@ gimp_palette_entry_set_color (const gchar *name,
/**
* gimp_palette_entry_get_name:
* @name: The palette name.
* @entry_num: The entry to retrieve.
* @entry_name: (out) (transfer full): The name requested.
* @palette: The palette.
* @entry_num: The entry to get.
* @entry_name: (out) (transfer full): The name of the entry.
*
* Gets the specified palette entry from the specified palette.
* Gets the name of an entry in the palette.
*
* This procedure retrieves the name of the zero-based entry specified
* for the specified palette. It returns an error if the entry does not
* exist.
* Gets the name of the entry at the zero-based index into the palette.
* Returns an error when the index is out of range.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_entry_get_name (const gchar *name,
gimp_palette_entry_get_name (GimpPalette *palette,
gint entry_num,
gchar **entry_name)
{
@ -588,7 +624,7 @@ gimp_palette_entry_get_name (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_INT, entry_num,
G_TYPE_NONE);
@ -611,22 +647,22 @@ gimp_palette_entry_get_name (const gchar *name,
/**
* gimp_palette_entry_set_name:
* @name: The palette name.
* @entry_num: The entry to retrieve.
* @palette: The palette.
* @entry_num: The entry to get.
* @entry_name: The new name.
*
* Sets the specified palette entry in the specified palette.
* Sets the name of an entry in the palette.
*
* This procedure sets the name of the zero-based entry specified for
* the specified palette. It returns an error if the entry does not
* exist.
* Sets the name of the entry at the zero-based index into the palette.
* Returns an error if the index is out or range. Returns an error if
* the palette is not editable.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_palette_entry_set_name (const gchar *name,
gimp_palette_entry_set_name (GimpPalette *palette,
gint entry_num,
const gchar *entry_name)
{
@ -635,7 +671,7 @@ gimp_palette_entry_set_name (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PALETTE, palette,
G_TYPE_INT, entry_num,
G_TYPE_STRING, entry_name,
G_TYPE_NONE);

View File

@ -32,37 +32,37 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gchar* gimp_palette_new (const gchar *name);
gchar* gimp_palette_duplicate (const gchar *name);
gchar* gimp_palette_rename (const gchar *name,
const gchar *new_name);
gboolean gimp_palette_delete (const gchar *name);
gboolean gimp_palette_is_editable (const gchar *name);
gboolean gimp_palette_get_info (const gchar *name,
gint *num_colors);
GimpRGB* gimp_palette_get_colors (const gchar *name,
gint *num_colors);
gint gimp_palette_get_columns (const gchar *name);
gboolean gimp_palette_set_columns (const gchar *name,
gint columns);
gboolean gimp_palette_add_entry (const gchar *name,
const gchar *entry_name,
const GimpRGB *color,
gint *entry_num);
gboolean gimp_palette_delete_entry (const gchar *name,
gint entry_num);
gboolean gimp_palette_entry_get_color (const gchar *name,
gint entry_num,
GimpRGB *color);
gboolean gimp_palette_entry_set_color (const gchar *name,
gint entry_num,
const GimpRGB *color);
gboolean gimp_palette_entry_get_name (const gchar *name,
gint entry_num,
gchar **entry_name);
gboolean gimp_palette_entry_set_name (const gchar *name,
gint entry_num,
const gchar *entry_name);
GimpPalette* gimp_palette_new (const gchar *name);
GimpPalette* gimp_palette_duplicate (GimpPalette *palette);
gboolean gimp_palette_id_is_valid (const gchar *id);
GimpPalette* gimp_palette_rename (GimpPalette *palette,
const gchar *new_name);
gboolean gimp_palette_delete (GimpPalette *palette);
gboolean gimp_palette_is_editable (GimpPalette *palette);
gint gimp_palette_get_color_count (GimpPalette *palette);
GimpRGB* gimp_palette_get_colors (GimpPalette *palette,
gint *num_colors);
gint gimp_palette_get_columns (GimpPalette *palette);
gboolean gimp_palette_set_columns (GimpPalette *palette,
gint columns);
gboolean gimp_palette_add_entry (GimpPalette *palette,
const gchar *entry_name,
const GimpRGB *color,
gint *entry_num);
gboolean gimp_palette_delete_entry (GimpPalette *palette,
gint entry_num);
gboolean gimp_palette_entry_get_color (GimpPalette *palette,
gint entry_num,
GimpRGB *color);
gboolean gimp_palette_entry_set_color (GimpPalette *palette,
gint entry_num,
const GimpRGB *color);
gboolean gimp_palette_entry_get_name (GimpPalette *palette,
gint entry_num,
gchar **entry_name);
gboolean gimp_palette_entry_set_name (GimpPalette *palette,
gint entry_num,
const gchar *entry_name);
G_END_DECLS

View File

@ -236,7 +236,7 @@ gimp_palette_select_button_get_palette (GimpPaletteSelectButton *button)
/**
* gimp_palette_select_button_set_palette:
* @button: A #GimpPaletteSelectButton
* @palette_name: (nullable): Palette name to set; %NULL means no change.
* @palette_name: (nullable): Palette name to set; %NULL means set to palette in context.
*
* Sets the current palette for the palette select button.
*
@ -259,17 +259,18 @@ gimp_palette_select_button_set_palette (GimpPaletteSelectButton *button,
else
{
gchar *name;
gint num_colors;
/* If not NULL and not empty string. */
if (palette_name && *palette_name)
name = g_strdup (palette_name);
name = palette_name;
else
name = gimp_context_get_palette ();
{
GimpPalette * palette = gimp_context_get_palette ();
if (gimp_palette_get_info (name, &num_colors))
gimp_palette_select_button_callback (name, FALSE, button);
name = gimp_resource_get_id (GIMP_RESOURCE (palette));
}
g_free (name);
gimp_palette_select_button_callback (name, FALSE, button);
}
}

View File

@ -0,0 +1,564 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/* this .c file is included by both
*
* libgimp/gimpparamspecs.c
* app/core/gimpparamspecs.c
*/
/*
* GIMP_TYPE_PARAM_BRUSH
*/
static void gimp_param_brush_class_init (GParamSpecClass *klass);
static void gimp_param_brush_init (GParamSpec *pspec);
static gboolean gimp_param_brush_validate (GParamSpec *pspec,
GValue *value);
GType
gimp_param_brush_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_brush_class_init,
NULL, NULL,
sizeof (GimpParamSpecBrush),
0,
(GInstanceInitFunc) gimp_param_brush_init
};
type = g_type_register_static (G_TYPE_PARAM_OBJECT,
"GimpParamBrush", &info, 0);
}
return type;
}
static void
gimp_param_brush_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_BRUSH;
klass->value_validate = gimp_param_brush_validate;
}
static void
gimp_param_brush_init (GParamSpec *pspec)
{
GimpParamSpecBrush *ispec = GIMP_PARAM_SPEC_BRUSH (pspec);
ispec->none_ok = FALSE;
}
static gboolean
gimp_param_brush_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecBrush *ispec = GIMP_PARAM_SPEC_BRUSH (pspec);
GimpBrush *brush = value->data[0].v_pointer;
if (! ispec->none_ok && brush == NULL)
return TRUE;
if (brush && (! GIMP_IS_BRUSH (brush) ||
! gimp_brush_is_valid (brush)))
{
g_object_unref (brush);
value->data[0].v_pointer = NULL;
return TRUE;
}
return FALSE;
}
/**
* gimp_param_spec_brush:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @none_ok: Whether no is a valid value.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecBrush specifying a
* #GIMP_TYPE_BRUSH property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #GimpParamSpecBrush.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_brush (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags)
{
GimpParamSpecBrush *ispec;
ispec = g_param_spec_internal (GIMP_TYPE_PARAM_BRUSH,
name, nick, blurb, flags);
g_return_val_if_fail (ispec, NULL);
ispec->none_ok = none_ok ? TRUE : FALSE;
return G_PARAM_SPEC (ispec);
}
/*
* GIMP_TYPE_PARAM_FONT
*/
static void gimp_param_font_class_init (GParamSpecClass *klass);
static void gimp_param_font_init (GParamSpec *pspec);
static gboolean gimp_param_font_validate (GParamSpec *pspec,
GValue *value);
GType
gimp_param_font_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_font_class_init,
NULL, NULL,
sizeof (GimpParamSpecFont),
0,
(GInstanceInitFunc) gimp_param_font_init
};
type = g_type_register_static (G_TYPE_PARAM_OBJECT,
"GimpParamFont", &info, 0);
}
return type;
}
static void
gimp_param_font_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_FONT;
klass->value_validate = gimp_param_font_validate;
}
static void
gimp_param_font_init (GParamSpec *pspec)
{
GimpParamSpecFont *ispec = GIMP_PARAM_SPEC_FONT (pspec);
ispec->none_ok = FALSE;
}
static gboolean
gimp_param_font_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecFont *ispec = GIMP_PARAM_SPEC_FONT (pspec);
GimpFont *font = value->data[0].v_pointer;
if (! ispec->none_ok && font == NULL)
return TRUE;
if (font && (! GIMP_IS_FONT (font) ||
! gimp_font_is_valid (font)))
{
g_object_unref (font);
value->data[0].v_pointer = NULL;
return TRUE;
}
return FALSE;
}
/**
* gimp_param_spec_font:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @none_ok: Whether no is a valid value.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecFont specifying a
* #GIMP_TYPE_FONT property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #GimpParamSpecFont.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_font (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags)
{
GimpParamSpecFont *ispec;
ispec = g_param_spec_internal (GIMP_TYPE_PARAM_FONT,
name, nick, blurb, flags);
g_return_val_if_fail (ispec, NULL);
ispec->none_ok = none_ok ? TRUE : FALSE;
return G_PARAM_SPEC (ispec);
}
/*
* GIMP_TYPE_PARAM_GRADIENT
*/
static void gimp_param_gradient_class_init (GParamSpecClass *klass);
static void gimp_param_gradient_init (GParamSpec *pspec);
static gboolean gimp_param_gradient_validate (GParamSpec *pspec,
GValue *value);
GType
gimp_param_gradient_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_gradient_class_init,
NULL, NULL,
sizeof (GimpParamSpecGradient),
0,
(GInstanceInitFunc) gimp_param_gradient_init
};
type = g_type_register_static (G_TYPE_PARAM_OBJECT,
"GimpParamGradient", &info, 0);
}
return type;
}
static void
gimp_param_gradient_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_GRADIENT;
klass->value_validate = gimp_param_gradient_validate;
}
static void
gimp_param_gradient_init (GParamSpec *pspec)
{
GimpParamSpecGradient *ispec = GIMP_PARAM_SPEC_GRADIENT (pspec);
ispec->none_ok = FALSE;
}
static gboolean
gimp_param_gradient_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecGradient *ispec = GIMP_PARAM_SPEC_GRADIENT (pspec);
GimpGradient *gradient = value->data[0].v_pointer;
if (! ispec->none_ok && gradient == NULL)
return TRUE;
if (gradient && (! GIMP_IS_GRADIENT (gradient) ||
! gimp_gradient_is_valid (gradient)))
{
g_object_unref (gradient);
value->data[0].v_pointer = NULL;
return TRUE;
}
return FALSE;
}
/**
* gimp_param_spec_gradient:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @none_ok: Whether no is a valid value.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecGradient specifying a
* #GIMP_TYPE_GRADIENT property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #GimpParamSpecGradient.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_gradient (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags)
{
GimpParamSpecGradient *ispec;
ispec = g_param_spec_internal (GIMP_TYPE_PARAM_GRADIENT,
name, nick, blurb, flags);
g_return_val_if_fail (ispec, NULL);
ispec->none_ok = none_ok ? TRUE : FALSE;
return G_PARAM_SPEC (ispec);
}
/*
* GIMP_TYPE_PARAM_PALETTE
*/
static void gimp_param_palette_class_init (GParamSpecClass *klass);
static void gimp_param_palette_init (GParamSpec *pspec);
static gboolean gimp_param_palette_validate (GParamSpec *pspec,
GValue *value);
GType
gimp_param_palette_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_palette_class_init,
NULL, NULL,
sizeof (GimpParamSpecPalette),
0,
(GInstanceInitFunc) gimp_param_palette_init
};
type = g_type_register_static (G_TYPE_PARAM_OBJECT,
"GimpParamPalette", &info, 0);
}
return type;
}
static void
gimp_param_palette_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_PALETTE;
klass->value_validate = gimp_param_palette_validate;
}
static void
gimp_param_palette_init (GParamSpec *pspec)
{
GimpParamSpecPalette *ispec = GIMP_PARAM_SPEC_PALETTE (pspec);
ispec->none_ok = FALSE;
}
static gboolean
gimp_param_palette_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecPalette *ispec = GIMP_PARAM_SPEC_PALETTE (pspec);
GimpPalette *palette = value->data[0].v_pointer;
if (! ispec->none_ok && palette == NULL)
return TRUE;
if (palette && (! GIMP_IS_PALETTE (palette) ||
! gimp_palette_is_valid (palette)))
{
g_object_unref (palette);
value->data[0].v_pointer = NULL;
return TRUE;
}
return FALSE;
}
/**
* gimp_param_spec_palette:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @none_ok: Whether no is a valid value.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecPalette specifying a
* #GIMP_TYPE_PALETTE property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #GimpParamSpecPalette.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_palette (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags)
{
GimpParamSpecPalette *ispec;
ispec = g_param_spec_internal (GIMP_TYPE_PARAM_PALETTE,
name, nick, blurb, flags);
g_return_val_if_fail (ispec, NULL);
ispec->none_ok = none_ok ? TRUE : FALSE;
return G_PARAM_SPEC (ispec);
}
/*
* GIMP_TYPE_PARAM_PATTERN
*/
static void gimp_param_pattern_class_init (GParamSpecClass *klass);
static void gimp_param_pattern_init (GParamSpec *pspec);
static gboolean gimp_param_pattern_validate (GParamSpec *pspec,
GValue *value);
GType
gimp_param_pattern_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) gimp_param_pattern_class_init,
NULL, NULL,
sizeof (GimpParamSpecPattern),
0,
(GInstanceInitFunc) gimp_param_pattern_init
};
type = g_type_register_static (G_TYPE_PARAM_OBJECT,
"GimpParamPattern", &info, 0);
}
return type;
}
static void
gimp_param_pattern_class_init (GParamSpecClass *klass)
{
klass->value_type = GIMP_TYPE_PATTERN;
klass->value_validate = gimp_param_pattern_validate;
}
static void
gimp_param_pattern_init (GParamSpec *pspec)
{
GimpParamSpecPattern *ispec = GIMP_PARAM_SPEC_PATTERN (pspec);
ispec->none_ok = FALSE;
}
static gboolean
gimp_param_pattern_validate (GParamSpec *pspec,
GValue *value)
{
GimpParamSpecPattern *ispec = GIMP_PARAM_SPEC_PATTERN (pspec);
GimpPattern *pattern = value->data[0].v_pointer;
if (! ispec->none_ok && pattern == NULL)
return TRUE;
if (pattern && (! GIMP_IS_PATTERN (pattern) ||
! gimp_pattern_is_valid (pattern)))
{
g_object_unref (pattern);
value->data[0].v_pointer = NULL;
return TRUE;
}
return FALSE;
}
/**
* gimp_param_spec_pattern:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @none_ok: Whether no is a valid value.
* @flags: Flags for the property specified.
*
* Creates a new #GimpParamSpecPattern specifying a
* #GIMP_TYPE_PATTERN property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #GimpParamSpecPattern.
*
* Since: 3.0
**/
GParamSpec *
gimp_param_spec_pattern (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags)
{
GimpParamSpecPattern *ispec;
ispec = g_param_spec_internal (GIMP_TYPE_PARAM_PATTERN,
name, nick, blurb, flags);
g_return_val_if_fail (ispec, NULL);
ispec->none_ok = none_ok ? TRUE : FALSE;
return G_PARAM_SPEC (ispec);
}

View File

@ -0,0 +1,173 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimp.h> can be included directly."
#endif
#ifndef __LIBGIMP_GIMP_PARAM_SPECS_RESOURCE_H__
#define __LIBGIMP_GIMP_PARAM_SPECS_RESOURCE_H__
G_BEGIN_DECLS
/*
* GIMP_TYPE_PARAM_BRUSH
*/
#define GIMP_VALUE_HOLDS_BRUSH(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_BRUSH))
#define GIMP_TYPE_PARAM_BRUSH (gimp_param_brush_get_type ())
#define GIMP_PARAM_SPEC_BRUSH(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_BRUSH, GimpParamSpecBrush))
#define GIMP_IS_PARAM_SPEC_BRUSH(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_BRUSH))
typedef struct _GimpParamSpecBrush GimpParamSpecBrush;
struct _GimpParamSpecBrush
{
GParamSpecObject parent_instance;
gboolean none_ok;
};
GType gimp_param_brush_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_brush (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags);
/*
* GIMP_TYPE_PARAM_FONT
*/
#define GIMP_VALUE_HOLDS_FONT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_FONT))
#define GIMP_TYPE_PARAM_FONT (gimp_param_font_get_type ())
#define GIMP_PARAM_SPEC_FONT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_FONT, GimpParamSpecFont))
#define GIMP_IS_PARAM_SPEC_FONT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_FONT))
typedef struct _GimpParamSpecFont GimpParamSpecFont;
struct _GimpParamSpecFont
{
GParamSpecObject parent_instance;
gboolean none_ok;
};
GType gimp_param_font_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_font (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags);
/*
* GIMP_TYPE_PARAM_GRADIENT
*/
#define GIMP_VALUE_HOLDS_GRADIENT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_GRADIENT))
#define GIMP_TYPE_PARAM_GRADIENT (gimp_param_gradient_get_type ())
#define GIMP_PARAM_SPEC_GRADIENT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_GRADIENT, GimpParamSpecGradient))
#define GIMP_IS_PARAM_SPEC_GRADIENT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_GRADIENT))
typedef struct _GimpParamSpecGradient GimpParamSpecGradient;
struct _GimpParamSpecGradient
{
GParamSpecObject parent_instance;
gboolean none_ok;
};
GType gimp_param_gradient_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_gradient (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags);
/*
* GIMP_TYPE_PARAM_PALETTE
*/
#define GIMP_VALUE_HOLDS_PALETTE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_PALETTE))
#define GIMP_TYPE_PARAM_PALETTE (gimp_param_palette_get_type ())
#define GIMP_PARAM_SPEC_PALETTE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_PALETTE, GimpParamSpecPalette))
#define GIMP_IS_PARAM_SPEC_PALETTE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_PALETTE))
typedef struct _GimpParamSpecPalette GimpParamSpecPalette;
struct _GimpParamSpecPalette
{
GParamSpecObject parent_instance;
gboolean none_ok;
};
GType gimp_param_palette_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_palette (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags);
/*
* GIMP_TYPE_PARAM_PATTERN
*/
#define GIMP_VALUE_HOLDS_PATTERN(value) (G_TYPE_CHECK_VALUE_TYPE ((value), GIMP_TYPE_PATTERN))
#define GIMP_TYPE_PARAM_PATTERN (gimp_param_pattern_get_type ())
#define GIMP_PARAM_SPEC_PATTERN(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GIMP_TYPE_PARAM_PATTERN, GimpParamSpecPattern))
#define GIMP_IS_PARAM_SPEC_PATTERN(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_PATTERN))
typedef struct _GimpParamSpecPattern GimpParamSpecPattern;
struct _GimpParamSpecPattern
{
GParamSpecObject parent_instance;
gboolean none_ok;
};
GType gimp_param_pattern_get_type (void) G_GNUC_CONST;
GParamSpec * gimp_param_spec_pattern (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean none_ok,
GParamFlags flags);
#define GIMP_VALUE_HOLDS_RESOURCE(value) (GIMP_VALUE_HOLDS_BRUSH (value) || GIMP_VALUE_HOLDS_FONT (value) || GIMP_VALUE_HOLDS_GRADIENT (value) || GIMP_VALUE_HOLDS_PALETTE (value) || GIMP_VALUE_HOLDS_PATTERN (value) )
G_END_DECLS
#endif /* __LIBGIMP_GIMP_PARAM_SPECS_RESOURCE_H__ */

View File

@ -32,3 +32,4 @@
* libgimp/ but need different headers.
*/
#include "gimpparamspecs-body.c"
#include "gimpparamspecs-body-resource.c"

View File

@ -30,30 +30,30 @@
/**
* SECTION: gimppattern
* @title: gimppattern
* @short_description: Functions operating on a single pattern.
* @short_description: Installable object used by fill and clone tools.
*
* Functions operating on a single pattern.
* Installable object used by fill and clone tools.
**/
/**
* gimp_pattern_get_info:
* @name: The pattern name.
* @pattern: The pattern.
* @width: (out): The pattern width.
* @height: (out): The pattern height.
* @bpp: (out): The pattern bpp.
*
* Retrieve information about the specified pattern.
* Gets information about the pattern.
*
* This procedure retrieves information about the specified pattern.
* This includes the pattern extents (width and height).
* Gets information about the pattern: the pattern extents (width and
* height) and bytes per pixel.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_pattern_get_info (const gchar *name,
gimp_pattern_get_info (GimpPattern *pattern,
gint *width,
gint *height,
gint *bpp)
@ -63,7 +63,7 @@ gimp_pattern_get_info (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PATTERN, pattern,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -91,25 +91,25 @@ gimp_pattern_get_info (const gchar *name,
/**
* gimp_pattern_get_pixels:
* @name: The pattern name.
* @pattern: The pattern.
* @width: (out): The pattern width.
* @height: (out): The pattern height.
* @bpp: (out): The pattern bpp.
* @num_color_bytes: (out): Number of pattern bytes.
* @color_bytes: (out) (array length=num_color_bytes) (element-type guint8) (transfer full): The pattern data.
*
* Retrieve information about the specified pattern (including pixels).
* Gets information about the pattern (including pixels).
*
* This procedure retrieves information about the specified. This
* includes the pattern extents (width and height), its bpp and its
* pixel data.
* Gets information about the pattern: the pattern extents (width and
* height), its bpp, and its pixel data. The pixel data is an array in
* C or a list in some languages.
*
* Returns: TRUE on success.
*
* Since: 2.2
**/
gboolean
gimp_pattern_get_pixels (const gchar *name,
gimp_pattern_get_pixels (GimpPattern *pattern,
gint *width,
gint *height,
gint *bpp,
@ -121,7 +121,7 @@ gimp_pattern_get_pixels (const gchar *name,
gboolean success = TRUE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, name,
GIMP_TYPE_PATTERN, pattern,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
@ -150,3 +150,39 @@ gimp_pattern_get_pixels (const gchar *name,
return success;
}
/**
* gimp_pattern_id_is_valid:
* @id: The pattern ID.
*
* Whether the ID is a valid reference to installed data.
*
* Returns TRUE if this ID is valid.
*
* Returns: TRUE if the pattern ID is valid.
*
* Since: 3.0
**/
gboolean
gimp_pattern_id_is_valid (const gchar *id)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean valid = FALSE;
args = gimp_value_array_new_from_types (NULL,
G_TYPE_STRING, id,
G_TYPE_NONE);
return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
"gimp-pattern-id-is-valid",
args);
gimp_value_array_unref (args);
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
valid = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
gimp_value_array_unref (return_vals);
return valid;
}

View File

@ -32,16 +32,17 @@ G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gboolean gimp_pattern_get_info (const gchar *name,
gint *width,
gint *height,
gint *bpp);
gboolean gimp_pattern_get_pixels (const gchar *name,
gint *width,
gint *height,
gint *bpp,
gint *num_color_bytes,
guint8 **color_bytes);
gboolean gimp_pattern_get_info (GimpPattern *pattern,
gint *width,
gint *height,
gint *bpp);
gboolean gimp_pattern_get_pixels (GimpPattern *pattern,
gint *width,
gint *height,
gint *bpp,
gint *num_color_bytes,
guint8 **color_bytes);
gboolean gimp_pattern_id_is_valid (const gchar *id);
G_END_DECLS

View File

@ -859,6 +859,33 @@ G_BEGIN_DECLS
g_value_take_object (gimp_value_array_index (args, n), value)
/* Resource */
#define GIMP_VALUES_GET_BRUSH(args, n) \
g_value_get_object (gimp_value_array_index (args, n))
#define GIMP_VALUES_SET_BRUSH(args, n, value) \
g_value_set_object (gimp_value_array_index (args, n), value)
#define GIMP_VALUES_GET_FONT(args, n) \
g_value_get_object (gimp_value_array_index (args, n))
#define GIMP_VALUES_SET_FONT(args, n, value) \
g_value_set_object (gimp_value_array_index (args, n), value)
#define GIMP_VALUES_GET_GRADIENT(args, n) \
g_value_get_object (gimp_value_array_index (args, n))
#define GIMP_VALUES_SET_GRADIENT(args, n, value) \
g_value_set_object (gimp_value_array_index (args, n), value)
#define GIMP_VALUES_GET_PALETTE(args, n) \
g_value_get_object (gimp_value_array_index (args, n))
#define GIMP_VALUES_SET_PALETTE(args, n, value) \
g_value_set_object (gimp_value_array_index (args, n), value)
#define GIMP_VALUES_GET_PATTERN(args, n) \
g_value_get_object (gimp_value_array_index (args, n))
#define GIMP_VALUES_SET_PATTERN(args, n, value) \
g_value_set_object (gimp_value_array_index (args, n), value)
G_END_DECLS
#endif /* __GIMP_PROCEDURE_PARAMS_H__ */

View File

@ -725,6 +725,12 @@ gimp_procedure_dialog_get_widget (GimpProcedureDialog *dialog,
property, NULL,
GTK_FILE_CHOOSER_ACTION_OPEN);
}
else if (G_IS_PARAM_SPEC_OBJECT (pspec) && pspec->value_type == GIMP_TYPE_BRUSH)
{
widget = gimp_prop_brush_chooser_button_new (G_OBJECT (dialog->priv->config),
property, NULL);
}
/* FIXME add cases for other resources. */
else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_ENUM)
{
GimpIntStore *store;

View File

@ -0,0 +1,299 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include <gegl-paramspecs.h>
#include <gtk/gtk.h>
#include "gimpui.h"
/* Several of these local functions were copied from gimppropwidgets.
* FUTURE: make utility functions shared by prop widgets.
*/
/* When property_name of object changes, call the callback passing callback_data. */
static void
connect_notify_property_changed (GObject *object,
const gchar *property_name,
GCallback callback,
gpointer callback_data)
{
gchar *notify_name;
notify_name = g_strconcat ("notify::", property_name, NULL);
g_signal_connect_object (object, notify_name, callback, callback_data, 0);
g_free (notify_name);
}
/* Setter and getters for a config property bound to a widget.
*
* A prop widget is responsible for knowing the config property it is bound to.
* The config property is a pair [config, property_name]
*
* The property name is unique among properties of the config.
* But it is not constant, and the config can have many similarly named properties,
* when the config has many properties each a value of type say GimpBrush.
* For example, the widget may have property "brush" but the config have "brush2"
*
* We arbitrarily store it in data, not in yet another property.
*/
static void
gimp_widget_set_bound_property (GtkWidget *widget,
GObject *config,
const gchar *property_name)
{
g_debug ("%s: %s", G_STRFUNC, property_name);
g_return_if_fail (GTK_IS_WIDGET (widget));
/* Widget destruction notifies this and frees the string. */
g_object_set_data_full (G_OBJECT (widget),
"gimp-widget-property-name",
g_strdup (property_name),
(GDestroyNotify) g_free);
g_object_set_data_full (G_OBJECT (widget),
"gimp-widget-property-config",
g_object_ref (config),
(GDestroyNotify) g_object_unref);
}
/* The result string is owned by the widget and is destroyed with the widget.
* Caller must copy it if caller needs it after the widget is destroyed.
*/
static const gchar *
gimp_widget_get_bound_property_name (GtkWidget *widget)
{
gchar * result=NULL;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
result = (gchar *) g_object_get_data (G_OBJECT (widget),
"gimp-widget-property-name");
/* Ensure result is NULL when set_bound_property was not called prior. */
g_debug ("bound to %s", result);
return result;
}
static GObject *
gimp_widget_get_bound_property_owner (GtkWidget *widget)
{
GObject * result=NULL;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
result = g_object_get_data (G_OBJECT (widget),
"gimp-widget-property-config");
/* Ensure result is NULL if the widget lacks the property.
* When set_bound_property was not called prior.
*/
g_debug("bound to owner %p", result);
return result;
}
static GParamSpec *
find_param_spec (GObject *object,
const gchar *property_name,
const gchar *strloc)
{
GParamSpec *param_spec;
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (object),
property_name);
if (! param_spec)
g_warning ("%s: %s has no property named '%s'",
strloc,
g_type_name (G_TYPE_FROM_INSTANCE (object)),
property_name);
return param_spec;
}
#ifdef DEBUG
/* Print the ID of a GimpResource */
static void
debug_resource_id(GimpBrush *property_value)
{
gchar * id;
g_object_get (GIMP_RESOURCE(property_value), "id", &id, NULL);
g_debug ("brush's id: %s", id);
}
#else
static void debug_resource_id(GimpBrush *property_value) {}
#endif
/* Called when the "brush" property of the widget changes.
*
* Do a prop widget's essential behavior:
* copy from widget property to GimpProcedureConfig property.
*
* Require the widget to have previously bound the config's property to itself.
* We don't compare current value with new value:
* that is an optimization to reduce signals.
* Only we are subscribed to this notify signal.
* The config is only being used to marshall args to a procedure call.
*/
static void
gimp_prop_brush_chooser_button_notify (GtkWidget *button)
{
GimpBrush *widget_property_value = NULL;
GimpBrush *config_property_value = NULL;
/* This pair designates a property of a GimpProcedureConfig. */
GObject *config;
const gchar *config_property_name;
/* Get changed value of the widget's property */
g_object_get (button, "brush", &widget_property_value, NULL);
debug_resource_id (widget_property_value);
/* Get the name of the config property the widget is bound to. */
config = gimp_widget_get_bound_property_owner (button);
config_property_name = gimp_widget_get_bound_property_name (button);
g_assert (config_property_name != NULL);
/* FUTURE: migrate much of this code to a new method
* GimpProcedureConfig.replace_object_value(property_name, new_value)
* It would know to free the existing value.
*/
/* Free the existing config property.
*
* Properties of type GObject might not have default value,
* so expect it can be NULL, when the config (settings) have never been serialized.
*
* Here we get a pointer to the object, and g_object_clear it.
* The config still points to the freed object, but we soon replace it.
*/
g_debug ("notify callback, get property: %s from config. ", config_property_name);
g_object_get (config, config_property_name, &config_property_value, NULL);
g_clear_object (&config_property_value);
/* Set the config's property to the widget's property */
g_object_set (config, config_property_name, widget_property_value, NULL);
/* Assert that g_object_set refs the value,
* so value won't be freed when widget closes.
*/
}
/**
* gimp_prop_brush_chooser_button_new:
* @config: Object to which property is attached.
* @property_name: Name of property controlled by button.
*
* Creates a #GimpBrushSelectButton that displays and sets the property,
* which is a GimpBrush.
*
* The button is labeled with the @property_name's nick.
*
* When pushed, the button shows a dialog that lets the user choose a brush.
*
* Returns: (transfer full): The newly created #GimpBrushSelectButton widget.
*
* Since: 3.0
*/
GtkWidget *
gimp_prop_brush_chooser_button_new (GObject *config,
const gchar *property_name,
const gchar *title)
{
GParamSpec *param_spec;
GtkWidget *button;
GimpBrush *brush;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (property_name != NULL, NULL);
g_debug ("config is %p", config);
g_debug ("property name is %s", property_name);
param_spec = find_param_spec (config, property_name, G_STRFUNC);
if (! param_spec)
{
g_warning ("%s: %s has no property named '%s'",
G_STRFUNC, g_type_name (G_TYPE_FROM_INSTANCE (config)),
property_name);
return NULL;
}
if (! G_IS_PARAM_SPEC_OBJECT (param_spec) || param_spec->value_type != GIMP_TYPE_BRUSH)
{
g_warning ("%s: property '%s' of %s is not a G_PARAM_SPEC_OBJECT of value type GIMP_TYPE_BRUSH.",
G_STRFUNC, param_spec->name,
g_type_name (param_spec->owner_type));
return NULL;
}
if (! title)
title = g_param_spec_get_nick (param_spec);
/* Initial choice in chooser is the brush of the config. */
/* Assert the property exists, but might be NULL. */
g_object_get (config, property_name, &brush, NULL);
if (brush == NULL)
{
/* Property has no default.
* Get a reasonable value from context.
* The widget will show some value selected,
* ensure it is the the value in context.
*/
g_warning ("No brush property in config. Using brush from context.");
brush = gimp_context_get_brush();
}
debug_resource_id (brush);
/* FIXME: use a widget that chooses only a brush,
* and not opacity, spacing, layer_mode.
*/
button = gimp_brush_select_button_new (title, brush,
1.0, 2, GIMP_LAYER_MODE_NORMAL);
/* Unlike other prop widgets, we don't use a callback for a signal of the widget.
* And we don't bind directly to a property.
* Instead get a callback for the notify signal of the widget "brush" property.
* Handler will copy widget's property to config's property.
*/
connect_notify_property_changed (
(GObject *)button, "brush", /* Source of signal. */
G_CALLBACK (gimp_prop_brush_chooser_button_notify), /* signal handler. */
button); /* Data passed to handler. */
/* widget knows what config property it is bound to. */
gimp_widget_set_bound_property (button, config, property_name);
/* FIXME: label the widget with the nick of the paramspec. */
gtk_widget_show (button);
return button;
}

View File

@ -0,0 +1,35 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_UI_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimpui.h> can be included directly."
#endif
#ifndef __GIMP_PROP_BRUSH_CHOOSER_H__
#define __GIMP_PROP_BRUSH_CHOOSER_H__
G_BEGIN_DECLS
GtkWidget * gimp_prop_brush_chooser_button_new (GObject *config,
const gchar *property_name,
const gchar *title);
G_END_DECLS
#endif /* __GIMP_PROP_BRUSH_CHOOSER_H__ */

View File

@ -0,0 +1,218 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gimp.h"
/*
* Subclasses of GimpResource.
*
* id_is_valid and other methods are in pdb/groups/<foo>.pd
*/
/* Each subclass:
* Is Final.
* Inherits GimpResource.
*
* See pdb/groups/<subclass>.pdb for:
* - annotations for a subclass,
* - more methods of a subclass,
*
* In bound languages, notation is Gimp.Brush.get_id()
* C code should use the superclass method, for example:
* gimp_resource_get_id (GIMP_RESOURCE (brush));
*
* For some methods, we need the same function name on the libgimp side and app/core side.
* Until gimp/core has a GimpResource class and GimpBrush derives from it,
* we must define the subclass specific gimp_brush_get_id method on the libgimp side.
*
* Some methods are in libgimp but not in the PDB e.g. is_valid
*
* Methods defined here may call class methods in the PDB.
* E.G. is_valid(self) calls class method id_is_valid(char *id)
*/
/* get_id is defined only for the superclass GimpResource.
* C code using libgimp can use: gimp_resource_get_id (GIMP_RESOURCE (brush))
* Note the macro to cast to the superclass to avoid compiler warnings.
* Bound languages can use for example: brush.get_id()
*/
/* Brush */
G_DEFINE_TYPE (GimpBrush, gimp_brush, GIMP_TYPE_RESOURCE);
static void gimp_brush_class_init (GimpBrushClass *klass) {}
static void gimp_brush_init (GimpBrush *self) {}
/**
* gimp_brush_is_valid:
* @self: The brush to check.
*
* Whether the brush has an ID that refers to installed data.
* The data might have been uninstalled after this object was created
* from saved settings.
*
* Returns: TRUE if the brush's ID refers to existing data.
*
* Since: 3.0
*/
gboolean
gimp_brush_is_valid (GimpBrush *self)
{
gchar *id;
/* Call superclass on cast self. */
id = gimp_resource_get_id (GIMP_RESOURCE (self));
/* Call class method in the PDB, which crosses the wire to core. */
return gimp_brush_id_is_valid (id);
}
/* Font */
G_DEFINE_TYPE (GimpFont, gimp_font, GIMP_TYPE_RESOURCE);
static void gimp_font_class_init (GimpFontClass *klass) {}
static void gimp_font_init (GimpFont *self) {}
/**
* gimp_font_is_valid:
* @self: The font to check.
*
* Whether the font has an ID that refers to installed data.
* The data might have been uninstalled after this object was created
* from saved settings.
*
* Returns: TRUE if the font's ID refers to existing data.
*
* Since: 3.0
*/
gboolean
gimp_font_is_valid (GimpFont *self)
{
gchar *id;
/* Call superclass on cast self. */
id = gimp_resource_get_id (GIMP_RESOURCE (self));
/* Call class method in the PDB, which crosses the wire to core. */
return gimp_font_id_is_valid (id);
}
/* Gradient */
G_DEFINE_TYPE (GimpGradient, gimp_gradient, GIMP_TYPE_RESOURCE);
static void gimp_gradient_class_init (GimpGradientClass *klass) {}
static void gimp_gradient_init (GimpGradient *self) {}
/**
* gimp_gradient_is_valid:
* @self: The gradient to check.
*
* Whether the gradient has an ID that refers to installed data.
* The data might have been uninstalled after this object was created
* from saved settings.
*
* Returns: TRUE if the gradient's ID refers to existing data.
*
* Since: 3.0
*/
gboolean
gimp_gradient_is_valid (GimpGradient *self)
{
gchar *id;
/* Call superclass on cast self. */
id = gimp_resource_get_id (GIMP_RESOURCE (self));
/* Call class method in the PDB, which crosses the wire to core. */
return gimp_gradient_id_is_valid (id);
}
/* Palette */
G_DEFINE_TYPE (GimpPalette, gimp_palette, GIMP_TYPE_RESOURCE);
static void gimp_palette_class_init (GimpPaletteClass *klass) {}
static void gimp_palette_init (GimpPalette *self) {}
/**
* gimp_palette_is_valid:
* @self: The palette to check.
*
* Whether the palette has an ID that refers to installed data.
* The data might have been uninstalled after this object was created
* from saved settings.
*
* Returns: TRUE if the palette's ID refers to existing data.
*
* Since: 3.0
*/
gboolean
gimp_palette_is_valid (GimpPalette *self)
{
gchar *id;
/* Call superclass on cast self. */
id = gimp_resource_get_id (GIMP_RESOURCE (self));
/* Call class method in the PDB, which crosses the wire to core. */
return gimp_palette_id_is_valid (id);
}
/* Pattern */
G_DEFINE_TYPE (GimpPattern, gimp_pattern, GIMP_TYPE_RESOURCE);
static void gimp_pattern_class_init (GimpPatternClass *klass) {}
static void gimp_pattern_init (GimpPattern *self) {}
/**
* gimp_pattern_is_valid:
* @self: The pattern to check.
*
* Whether the pattern has an ID that refers to installed data.
* The data might have been uninstalled after this object was created
* from saved settings.
*
* Returns: TRUE if the pattern's ID refers to existing data.
*
* Since: 3.0
*/
gboolean
gimp_pattern_is_valid (GimpPattern *self)
{
gchar *id;
/* Call superclass on cast self. */
id = gimp_resource_get_id (GIMP_RESOURCE (self));
/* Call class method in the PDB, which crosses the wire to core. */
return gimp_pattern_id_is_valid (id);
}

View File

@ -0,0 +1,95 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimp.h> can be included directly."
#endif
#ifndef __LIBGIMP_GIMP_RESOURCE_SUBCLASS_H__
#define __LIBGIMP_GIMP_RESOURCE_SUBCLASS_H__
G_BEGIN_DECLS
/*
* Subclasses of GimpResource.
*
* id_is_valid and other methods are in pdb/groups/<foo>.pd
*/
#define GIMP_TYPE_BRUSH (gimp_brush_get_type ())
G_DECLARE_FINAL_TYPE (GimpBrush, gimp_brush, GIMP, BRUSH, GimpResource)
struct _GimpBrush
{
GimpResource parent_instance;
};
gboolean gimp_brush_is_valid (GimpBrush *self);
#define GIMP_TYPE_FONT (gimp_font_get_type ())
G_DECLARE_FINAL_TYPE (GimpFont, gimp_font, GIMP, FONT, GimpResource)
struct _GimpFont
{
GimpResource parent_instance;
};
gboolean gimp_font_is_valid (GimpFont *self);
#define GIMP_TYPE_GRADIENT (gimp_gradient_get_type ())
G_DECLARE_FINAL_TYPE (GimpGradient, gimp_gradient, GIMP, GRADIENT, GimpResource)
struct _GimpGradient
{
GimpResource parent_instance;
};
gboolean gimp_gradient_is_valid (GimpGradient *self);
#define GIMP_TYPE_PALETTE (gimp_palette_get_type ())
G_DECLARE_FINAL_TYPE (GimpPalette, gimp_palette, GIMP, PALETTE, GimpResource)
struct _GimpPalette
{
GimpResource parent_instance;
};
gboolean gimp_palette_is_valid (GimpPalette *self);
#define GIMP_TYPE_PATTERN (gimp_pattern_get_type ())
G_DECLARE_FINAL_TYPE (GimpPattern, gimp_pattern, GIMP, PATTERN, GimpResource)
struct _GimpPattern
{
GimpResource parent_instance;
};
gboolean gimp_pattern_is_valid (GimpPattern *self);
G_END_DECLS
#endif /* __LIBGIMP_GIMP_RESOURCE_SUBCLASS_H__ */

344
libgimp/gimpresource.c Normal file
View File

@ -0,0 +1,344 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gimp.h"
/* deriveable type not included in gimp.h. */
#include "gimpresource.h"
/* GimpResource: base class for resources.
*
* Known subclasses are Font, Brush, Pattern, Palette, Gradient.
* FUTURE: ? Dynamics, ToolPreset, ColorProfile, Color, ColorScale
* (GimpParasite is NOT.)
*
* A *resource* is data that GIMP loads at runtime startup,
* where the data is used by drawing tools.
* The GimpContext holds a user's current choice of resources.
* The GIMP core has the *resource* data.
*
* A resource has-a identifier.
* Currently the identifier is a string, sometimes called a name.
* The identifier is unique among instances(resource datas) loaded into GIMP.
*
* A user can change the set of resources installed with GIMP,
* and edit or create new resources meaning datasets.
* A user may attempt to install two different resources having the same name.
* A user may uninstall a resource while there are still references to it in settings.
*
* FUTURE: the identifier is world unique, a UUID or an integer incremented by core.
* Uniqueness is enforced by core.
*
* A GimpResource's identifier is serialized as a setting, i.e. a user's choice,
* A serialization of a GimpResource is *not* the serialization of the
* resource's underlying data e.g. not the pixels of a brush.
*
* The GimpResource identifier is opaque: you should only pass it around.
* You should not assume it has any human readable meaning (although it does now.)
* You should not assume that the "id" is a string.
* The Resource class encapsulates the ID so in the future, the type may change.
* PDB procedures that pass a string ID for a resource are obsolete.
*
* Usually a plugin lets a user choose a resource interactively
* then sets it into a temporary context to affect subsequent operations.
*
* The Gimp architecture for plugins uses remote procedures,
* and identically named classes on each side of the wire.
* A GimpBrush class in core is not the same class as GimpBrush in libgimp.
* a GimpResource on the libgimp side is a proxy.
* There is no GimpResource class in core.
*
* One use of GimpResource and its subclasses
* is as a held type of GParamSpecObject, used to declare the parameters of a PDB procedure.
* A GimpResource is serializable just for the purpose of serializing GimpProcedureConfig,
* a "settings" i.e. a set of values for the arguments to a GimpProcedure.
* A GimpResource just holds the id as a way to identify a *resource*
* in calls to PDB procedures that ultimately access the core instance of the resource.
* A GimpResource that has been serialized in a GimpConfig refers to a *resource*
* that might not still exist in core in the set of loaded resources (files.)
*
* A GimpResource:
* - furnishes its ID as a property
* - serializes/deserializes itself (implements GimpConfigInterface)
*
* Some subclasses e.g. GimpFont are pure types.
* That is, inheriting all its properties and methods from GimpResource.
* Such a pure type exists just to distinguish (by the name of its type)
* from other subclasses of GimpResource.
*
* Some subclasses have methods for getting/setting attributes of a resource.
* Some subclasses have methods for creating, duplicating, and deleting resources.
* Most methods are defined in the PDB (in .pdb files.)
*
* Internally, you may need to create a proxy object. Use:
* brush = g_object_new (GIMP_TYPE_BRUSH, NULL);
* g_object_set (GIMP_RESOURCE(brush), "id", "foo name", NULL);
* This does NOT create the resource's data in core, only a reference to it.
* When there is no underlying resource of that id (name) in core,
* the brush is invalid.
*/
enum
{
PROP_0,
PROP_ID,
N_PROPS
};
/* Private structure definition. */
typedef struct {
char *id;
} GimpResourcePrivate;
static void gimp_resource_finalize (GObject *object);
static void gimp_resource_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_resource_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
/* Implementation of the GimpConfigInterface */
static void gimp_resource_config_iface_init (GimpConfigInterface *iface);
static gboolean gimp_resource_serialize (GimpConfig *config,
GimpConfigWriter *writer,
gpointer data);
static gboolean gimp_resource_deserialize (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gpointer data);
/* The class type is both deriveable (has private) AND implements interface. */
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GimpResource, gimp_resource, G_TYPE_OBJECT,
G_ADD_PRIVATE (GimpResource)
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
gimp_resource_config_iface_init))
#define parent_class gimp_resource_parent_class
static GParamSpec *props[N_PROPS] = { NULL, };
/* Class construction */
static void
gimp_resource_class_init (GimpResourceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
g_debug("gimp_resource_class_init");
object_class->finalize = gimp_resource_finalize;
object_class->set_property = gimp_resource_set_property;
object_class->get_property = gimp_resource_get_property;
props[PROP_ID] =
g_param_spec_string ("id",
"The id",
"The id for internal use",
"unknown",
GIMP_PARAM_READWRITE);
g_object_class_install_properties (object_class, N_PROPS, props);
}
/* Instance construction. */
static void
gimp_resource_init (GimpResource *self)
{
/* Initialize private data to 0 */
GimpResourcePrivate *priv = gimp_resource_get_instance_private (self);
priv->id = NULL;
g_debug("gimp_resource_init");
}
/* The next comment annotates the class. */
/**
* GimpResource:
*
* Installable data having serializable ID. Superclass of Font, Brush, etc.
**/
/**
* gimp_resource_get_id:
* @self: The resource.
*
* Returns an internal key to the store of resources in the core app.
* The key can be invalid after a user uninstalls or deletes a resource.
*
* Returns: (transfer none): the resource's ID.
*
* Since: 3.0
**/
gchar *
gimp_resource_get_id (GimpResource *self)
{
GimpResourcePrivate *priv = gimp_resource_get_instance_private (self);
return self ? priv->id : "";
}
/* Two stage dispose/finalize.
* We don't need dispose since no objects to unref. id is a string, not a GObject.
* Some docs say must define both.
*/
static void
gimp_resource_finalize (GObject *self)
{
GimpResourcePrivate *priv = gimp_resource_get_instance_private (GIMP_RESOURCE(self));
g_debug ("gimp_resource_finalize");
/* Free string property. g_clear_pointer is safe if already freed. */
g_clear_pointer (&priv->id, g_free);
/* Chain up. */
G_OBJECT_CLASS (parent_class)->finalize (self);
}
/*
* Override the GObject methods for set/get property.
* i.e. override g_object_set_property.
*/
static void
gimp_resource_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpResource *self = GIMP_RESOURCE (object);
GimpResourcePrivate *priv = gimp_resource_get_instance_private (self);
g_debug ("gimp_resource_set_property");
switch (property_id)
{
case PROP_ID:
g_free (priv->id);
priv->id = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_resource_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpResource *self = GIMP_RESOURCE (object);
GimpResourcePrivate *priv = gimp_resource_get_instance_private (self);
g_debug ("gimp_resource_get_property");
switch (property_id)
{
case PROP_ID:
g_value_set_string (value, priv->id);
/* Assert id string was copied into GValue. */
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
/* config iface */
static void
gimp_resource_config_iface_init (GimpConfigInterface *iface)
{
/* We don't implement the serialize_property methods. */
iface->deserialize = gimp_resource_deserialize;
iface->serialize = gimp_resource_serialize;
}
/* Serialize the whole thing, which is the id.
*
* Requires the id is not NULL.
* When id is NULL, writes nothing and returns FALSE.
*/
static gboolean
gimp_resource_serialize (GimpConfig *config,
GimpConfigWriter *writer,
gpointer data) /* Unused. */
{
/* Require config is-a GimpResource instance implementing Config iface. */
GimpResource *self = GIMP_RESOURCE (config);
GimpResourcePrivate *priv = gimp_resource_get_instance_private (self);
g_debug ("resource serialize");
if (priv->id != NULL)
{
g_debug ("resource serialize: %s", priv->id);
/* require the caller opened and will close writer.
* Caller wrote the subclass type name "Gimp<Foo>"
*/
gimp_config_writer_string (writer, priv->id);
return TRUE;
}
else
{
g_debug ("resource serialize failed: NULL id");
return FALSE;
}
}
static gboolean
gimp_resource_deserialize (GimpConfig *config,
GScanner *scanner,
gint nest_level,
gpointer data)
{
gchar *id;
GimpResource *self = GIMP_RESOURCE (config);
GimpResourcePrivate *priv = gimp_resource_get_instance_private (self);
g_debug ("resource deserialize");
if (! gimp_scanner_parse_string (scanner, &id))
{
g_scanner_error (scanner,
"Fail scan string for resource");
return FALSE;
}
else
{
g_debug ("resource deserialize: %s", id);
priv->id = id;
}
return TRUE;
}

51
libgimp/gimpresource.h Normal file
View File

@ -0,0 +1,51 @@
/* LIBGIMP - The GIMP Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
#error "Only <libgimp/gimp.h> can be included directly."
#endif
#ifndef __GIMP_RESOURCE_H__
#define __GIMP_RESOURCE_H__
G_BEGIN_DECLS
/* Inherits GObject. Inheritable by e.g. GimpBrush. */
#define GIMP_TYPE_RESOURCE (gimp_resource_get_type ())
G_DECLARE_DERIVABLE_TYPE (GimpResource, gimp_resource, GIMP, RESOURCE, GObject)
struct _GimpResourceClass
{
GObjectClass parent_class;
/* Padding for future expansion */
void (*_gimp_reserved1) (void);
void (*_gimp_reserved2) (void);
void (*_gimp_reserved3) (void);
void (*_gimp_reserved4) (void);
void (*_gimp_reserved5) (void);
void (*_gimp_reserved6) (void);
void (*_gimp_reserved7) (void);
void (*_gimp_reserved8) (void);
};
gchar * gimp_resource_get_id (GimpResource *self);
G_END_DECLS
#endif /* __GIMP_RESOURCE_H__ */

View File

@ -61,6 +61,7 @@ EXPORTS
gimp_procedure_dialog_set_sensitive
gimp_progress_bar_get_type
gimp_progress_bar_new
gimp_prop_brush_chooser_button_new
gimp_save_procedure_dialog_add_metadata
gimp_save_procedure_dialog_get_type
gimp_save_procedure_dialog_new

View File

@ -46,6 +46,7 @@
#include <libgimp/gimpsaveproceduredialog.h>
#include <libgimp/gimpselectbutton.h>
#include <libgimp/gimpzoompreview.h>
#include <libgimp/gimppropbrushchooser.h>
#undef __GIMP_UI_H_INSIDE__

View File

@ -75,6 +75,7 @@ pdb_wrappers_sources = [
'gimpedit_pdb.c',
'gimpfile_pdb.c',
'gimpfloatingsel_pdb.c',
'gimpfont_pdb.c',
'gimpfonts_pdb.c',
'gimpfontselect_pdb.c',
'gimpgimprc_pdb.c',
@ -127,6 +128,7 @@ pdb_wrappers_headers = [
'gimpedit_pdb.h',
'gimpfile_pdb.h',
'gimpfloatingsel_pdb.h',
'gimpfont_pdb.h',
'gimpfonts_pdb.h',
'gimpfontselect_pdb.h',
'gimpgimprc_pdb.h',
@ -189,6 +191,8 @@ libgimp_sources_introspectable = [
'gimpprocedure.c',
'gimpprocedureconfig.c',
'gimpprogress.c',
'gimpresource.c',
'gimpresource-subclass.c',
'gimpsaveprocedure.c',
'gimpselection.c',
'gimptextlayer.c',
@ -239,12 +243,15 @@ libgimp_headers_introspectable = [
'gimploadprocedure.h',
'gimppaletteselect.h',
'gimpparamspecs.h',
'gimpparamspecs-resource.h',
'gimppatternselect.h',
'gimppdb.h',
'gimpplugin.h',
'gimpprocedure.h',
'gimpprocedureconfig.h',
'gimpprogress.h',
'gimpresource.h',
'gimpresource-subclass.h',
'gimpsaveprocedure.h',
'gimpselection.h',
'gimptextlayer.h',
@ -260,6 +267,7 @@ libgimp_headers = [
libgimpui_sources_introspectable = [
'gimpaspectpreview.c',
'gimppropbrushchooser.c',
'gimpbrushselectbutton.c',
'gimpdrawablepreview.c',
'gimpexport.c',
@ -412,6 +420,7 @@ libgimp_introspectable_files = [
libgimpmath_introspectable,
libgimpmodule_introspectable,
'gimpparamspecs-body.c',
'gimpparamspecs-body-resource.c',
]
libgimpui_introspectable_files = [

View File

@ -0,0 +1,263 @@
"""
Python scripts to test libgimp API.
Specifically, test GimpResource class and subclasses.
Test methods common to most resource classes, and class methods.
Methods specific to each class are tested elsewhere.
Usage:
=====
This is not a GIMP plugin.
Just copy and paste into the GIMP Python Console.
Expect no exceptions.
You can quickly look for red text.
There are no messages from the test program,
only exceptions from assert to indicate a failure.
Requires PyGObject binding to libgimp,
which the GIMP Python Console does automatically.
Trash:
=====
This test program may leave trash, especially for failed runs.
Trash means resources persisted by GIMP.
!!! Do not run this in a production environment (using GIMP to create graphics.)
You can run it in a GIMP development environment,
but you may need to clean up trash manually.
Deleting the .config/GIMP directory will clean up the trash.
Setup in the GIMP app:
=====================
Choose current resources to match what this test uses:
e.g. brush '2. Hardness 050'
Use the standard default initial resources for a clean build,
by deleting .config/GIMP.
Ensure test resources from prior runs are deleted
otherwise they interfere with testing i.e. name clash.
E.g. delete brush '2. Hardness 050 copy #1'
"""
"""
Test return value is-a resource.
Get resource from context
"""
brush = Gimp.context_get_brush()
font = Gimp.context_get_font()
gradient = Gimp.context_get_gradient()
palette = Gimp.context_get_palette()
pattern = Gimp.context_get_pattern()
assert isinstance(brush, Gimp.Brush)
assert isinstance(font, Gimp.Font)
assert isinstance(gradient, Gimp.Gradient)
assert isinstance(palette, Gimp.Palette)
assert isinstance(pattern, Gimp.Pattern)
"""
Test is_valid method
Expect True
"""
assert brush.is_valid()
assert font.is_valid()
assert gradient.is_valid()
assert palette.is_valid()
assert pattern.is_valid()
"""
Test get_id method
Expect string
"""
print( brush.get_id() )
print( font.get_id() )
print( gradient.get_id() )
print( palette.get_id() )
print( pattern.get_id() )
assert brush.get_id() == '2. Hardness 050'
assert font.get_id() == 'Sans-serif'
assert gradient.get_id() == 'FG to BG (RGB)'
assert palette.get_id() == 'Color History'
assert pattern.get_id() == 'Pine'
"""
Test resource as an arg
Pass the resource back to the context
Expect no exceptions
"""
assert Gimp.context_set_brush(brush) == True
assert Gimp.context_set_font(font) == True
assert Gimp.context_set_gradient(gradient) == True
assert Gimp.context_set_palette(palette) == True
assert Gimp.context_set_pattern(pattern) == True
"""
Test new() methods
Not Font, Pattern.
Pass desired name.
"""
brush_new = Gimp.Brush.new("New Brush")
# expect a valid brush object, not a name
assert brush_new.is_valid()
# expect id is the desired one (assuming no clash)
assert brush_new.get_id()=="New Brush"
gradient_new = Gimp.Gradient.new("New Gradient")
assert gradient_new.is_valid()
assert gradient_new.get_id()=="New Gradient"
palette_new = Gimp.Palette.new("New Palette")
assert palette_new.is_valid()
assert palette_new.get_id()=="New Palette"
"""
Test delete methods.
Delete the new resources we just made
After deletion, reference is invalid
"""
assert brush_new.delete() == True
assert brush_new.is_valid()==False
assert gradient_new.delete() == True
assert gradient_new.is_valid()==False
assert palette_new.delete() == True
assert palette_new.is_valid()==False
"""
Test copy methods.
Copy the original resources from context.
Assert that GIMP adds " copy"
"""
brush_copy = brush.duplicate()
assert brush_copy.is_valid()
assert brush_copy.get_id()=='2. Hardness 050 copy'
gradient_copy = gradient.duplicate()
assert gradient_copy.is_valid()
assert gradient_copy.get_id()=='FG to BG (RGB) copy'
palette_copy = palette.duplicate()
assert palette_copy.is_valid()
assert palette_copy.get_id()== 'Color History copy'
"""
Test rename methods.
Renaming returns a reference that must be kept. !!!
Rename existing copy to a desired name.
!!! assign to a new named var
"""
brush_renamed = brush_copy.rename("Renamed Brush")
assert brush_renamed.is_valid()
assert brush_renamed.get_id()=="Renamed Brush"
# assert renaming invalidates any old reference,
assert brush_copy.is_valid()==False
gradient_renamed = gradient_copy.rename("Renamed Gradient")
assert gradient_renamed.is_valid()
assert gradient_renamed.get_id()=="Renamed Gradient"
# assert renaming invalidates any old reference,
assert gradient_copy.is_valid()==False
palette_renamed = palette_copy.rename("Renamed Palette")
assert palette_renamed.is_valid()
assert palette_renamed.get_id()=="Renamed Palette"
# assert renaming invalidates any old reference,
assert palette_copy.is_valid()==False
"""
Test renaming when name is already in use.
If "Renamed Brush" is already in use, then the name will be
"Renamed Brush copy #1"
that is, renaming added suffix "#1"
This is due to core behavior, not libgimp resource class per se,
so we don't test it here.
"""
"""
Test delete methods
Delete the renamed copies we just made
After deletion, reference is invalid
"""
brush_renamed.delete()
assert brush_renamed.is_valid()==False
gradient_renamed.delete()
assert gradient_renamed.is_valid()==False
palette_renamed.delete()
assert palette_renamed.is_valid()==False
'''
Test class method
!!! Expect no error dialog in GIMP.
The app code generated from foo.pdb should clear the GError.
'''
assert Gimp.Brush.id_is_valid ("invalid name")==False
assert Gimp.Font.id_is_valid ("invalid name")==False
assert Gimp.Gradient.id_is_valid("invalid name")==False
assert Gimp.Palette.id_is_valid ("invalid name")==False
assert Gimp.Pattern.id_is_valid ("invalid name")==False
'''
Test constructor
Not something author's should do, but test it anyway
'''
brush2 = Gimp.Brush()
font2 = Gimp.Font()
gradient2 = Gimp.Gradient()
palette2 = Gimp.Palette()
pattern2 = Gimp.Pattern()
assert isinstance(brush2, Gimp.Brush)
assert isinstance(font2, Gimp.Font)
assert isinstance(gradient2, Gimp.Gradient)
assert isinstance(palette2, Gimp.Palette)
assert isinstance(pattern2, Gimp.Pattern)
# a created instance is invalid until it's ID is set
assert brush2.is_valid()==False
assert font2.is_valid()==False
assert gradient2.is_valid()==False
assert palette2.is_valid()==False
assert pattern2.is_valid()==False
"""
test set_property methods
Use a name that exists. Creating de novo a reference to an existing brush.
Reference is valid since it's data exists in app core
"""
brush2.set_property("id", "2. Star")
assert brush2.get_id()=="2. Star"
assert brush2.is_valid()
font2.set_property("id", "Sans-serif")
assert font2.get_id() =="Sans-serif"
assert font2.is_valid()
gradient2.set_property("id", 'FG to BG (RGB)')
assert gradient2.get_id() =='FG to BG (RGB)'
assert gradient2.is_valid()
palette2.set_property("id", 'Color History')
assert palette2.get_id() =='Color History'
assert palette2.is_valid()
pattern2.set_property("id", 'Pine')
assert pattern2.get_id() =='Pine'
assert pattern2.is_valid()

336
libgimp/test/test_brush.py Normal file
View File

@ -0,0 +1,336 @@
"""
Python scripts to test GimpBrush class of libgimp API.
See comments about usage and setup in test-resource-class.py
Setup: "2. Hardness 050" brush is selected.
Testing context_set_brush
and a few other tests of class methods
are in test_resource_class.py
FUTURE: revise comparison of floats to within epsilon
"""
"""
Test a known, stock, parametric brush "2. Hardness 050"
********************************************************************************
Numeric literals might change if gimp devs change defaults.
"""
brush_default = Gimp.context_get_brush()
print( brush_default.get_id() )
assert brush_default.get_id() == "2. Hardness 050"
assert brush_default.is_generated()
assert not brush_default.is_editable()
"""
Test getters of default, stock (not editable), parametric brush
"""
success, width, height, mask_bpp, color_bpp = brush_default.get_info()
print( width, height, mask_bpp, color_bpp )
assert success
assert width == 51
assert height == 51
assert mask_bpp == 1
# !!! Since parametric, not pixmap and color_bpp is zero
assert color_bpp == 0
success, width, height, mask_bpp, mask, color_bpp, pixels = brush_default.get_pixels()
print( width, height, mask_bpp, len(mask), color_bpp, len(pixels) )
assert success
assert width == 51
assert height == 51
assert mask_bpp == 1
# !!! Since parametric, not pixmap and color_bpp is zero
assert color_bpp == 0
assert len(mask) == 2601
assert len(pixels) == 0
# !!! spacing does not return success, only a value
spacing = brush_default.get_spacing()
print(spacing)
assert spacing == 10
# shape, radius, spikes, hardness, aspect_ratio, angle
success, shape = brush_default.get_shape()
assert success
print(shape)
assert shape == Gimp.BrushGeneratedShape.CIRCLE
success, radius = brush_default.get_radius()
assert success
print(radius)
assert radius == 25.0
success, spikes = brush_default.get_spikes()
assert success
print(spikes)
assert spikes == 2
success, hardness = brush_default.get_hardness()
assert success
print(hardness)
assert hardness == 0.5
success, aspect_ratio = brush_default.get_aspect_ratio()
assert success
print(aspect_ratio)
assert aspect_ratio == 1.0
success, angle = brush_default.get_angle()
assert success
print(angle)
assert angle == 0.0
"""
Test set_spacing fails on not editable brush.
"""
success = brush_default.set_spacing(1)
assert not success
# spacing did not change
assert brush_default.get_spacing() == 10
"""
Test setters fail on non-editable brush.
When they fail, they return a value that is nullish
"""
success, returned_shape = brush_default.set_shape(Gimp.BrushGeneratedShape.DIAMOND)
print(success, returned_shape)
assert not success
assert returned_shape is Gimp.BrushGeneratedShape.CIRCLE
success, returned_radius = brush_default.set_radius(1.0)
print(success, returned_radius)
assert not success
assert returned_radius == 0.0
success, returned_spikes = brush_default.set_spikes(1.0)
print(success, returned_spikes)
assert not success
assert returned_spikes == 0
success, returned_hardness = brush_default.set_hardness(1.0)
print(success, returned_hardness)
assert not success
assert returned_hardness == 0.0
success, returned_aspect_ratio = brush_default.set_aspect_ratio(1.0)
print(success, returned_aspect_ratio)
assert not success
success, returned_angle = brush_default.set_angle(1.0)
assert not success
"""
Test non-parametric brush i.e. raster, and stock i.e. not editable
********************************************************************************
No method exists to get a specific brush.
But we can set the ID of a new brush.
"""
brush_raster = Gimp.Brush()
brush_raster.set_property("id", "Acrylic 01")
assert brush_raster.get_id() == "Acrylic 01"
assert brush_raster.is_valid()
# raster brush is not parametric
assert not brush_raster.is_generated()
# This brush is not editable
assert not brush_raster.is_editable()
# Raster brush has spacing
spacing = brush_raster.get_spacing()
print(spacing)
assert spacing == 25
# Getters of attributes of parametric brush fail for raster brush
success, shape = brush_raster.get_shape()
assert not success
success, radius = brush_raster.get_radius()
assert not success
success, spikes = brush_raster.get_spikes()
assert not success
success, hardness = brush_raster.get_hardness()
assert not success
success, aspect_ratio = brush_raster.get_aspect_ratio()
assert not success
success, angle = brush_raster.get_angle()
assert not success
"""
Test raster brush of kind color has pixel data.
"""
brush_color = Gimp.Brush()
brush_color.set_property("id", "z Pepper")
assert brush_color.is_valid()
success, width, height, mask_bpp, mask, color_bpp, pixels = brush_color.get_pixels()
print( width, height, mask_bpp, len(mask), color_bpp, len(pixels) )
assert success
# !!! Since is color and raster, has pixmap and color_bpp is non-zero
assert color_bpp == 3
assert len(pixels) > 0
"""
Test setting spacing on not editable, raster brush
"""
success = brush_raster.set_spacing(1)
assert not success
# spacing did not change
assert brush_raster.get_spacing() == 25
"""
Test setters fails on raster brush.
"""
success, returned_shape = brush_raster.set_shape(Gimp.BrushGeneratedShape.DIAMOND)
print(success, returned_shape)
assert not success
# Returned value is integer 0, corresponding to CIRCLE enum
assert returned_shape is Gimp.BrushGeneratedShape.CIRCLE
success, returned_radius = brush_raster.set_radius(1.0)
assert not success
success, returned_spikes = brush_raster.set_spikes(1.0)
assert not success
success, returned_hardness = brush_raster.set_hardness(1.0)
assert not success
success, returned_aspect_ratio = brush_raster.set_aspect_ratio(1.0)
assert not success
success, returned_angle = brush_raster.set_angle(1.0)
assert not success
"""
Test new brush
********************************************************************************
Parametric and editable
"""
brush_new = Gimp.Brush.new("New Brush")
# is generated and editable
assert brush_new.is_generated()
assert brush_new.is_editable()
"""
Test setters on editable brush.
"""
success = brush_new.set_spacing(20)
assert success == True
spacing = brush_new.get_spacing()
assert spacing == 20
success, returned_shape = brush_new.set_shape(Gimp.BrushGeneratedShape.DIAMOND)
print(success)
assert success == True
assert returned_shape == Gimp.BrushGeneratedShape.DIAMOND
success, shape = brush_new.get_shape()
assert success == True
assert shape == Gimp.BrushGeneratedShape.DIAMOND
success, returned_radius = brush_new.set_radius(4.0)
assert success == True
print(returned_radius)
assert returned_radius == 4.0
success, radius = brush_new.get_radius()
assert success == True
assert radius == 4.0
success, returned_spikes = brush_new.set_spikes(2)
assert success == True
assert returned_spikes == 2
success, spikes = brush_new.get_spikes()
assert success == True
assert spikes == 2
success, returned_hardness = brush_new.set_hardness(0.5)
assert success == True
print(returned_hardness)
assert returned_hardness == 0.5
success, hardness = brush_new.get_hardness()
assert success == True
assert hardness == 0.5
success, returned_aspect_ratio = brush_new.set_aspect_ratio(5.0)
assert success == True
print(returned_aspect_ratio)
assert returned_aspect_ratio == 5.0
success, aspect_ratio = brush_new.get_aspect_ratio()
assert success == True
assert aspect_ratio == 5.0
success, returned_angle = brush_new.set_angle(90.0)
assert success == True
print(returned_angle)
assert returned_angle == 90.0
success, angle = brush_new.get_angle()
assert success == True
assert angle == 90.0
"""
Test invalid enum for shape.
"""
# TODO it yields a TypeError
"""
Test clamping at upper limits.
"""
'''
Omitting this test for now. Possible bug.
The symptoms are that it takes a long time,
and then GIMP crashes.
success, returned_radius = brush_new.set_radius(40000)
assert success == True
# upper clamp
assert returned_radius == 32767.0
success, radius = brush_new.get_radius()
assert success == True
assert radius == 32767.0
'''
success, returned_spikes = brush_new.set_spikes(22)
assert success == True
assert returned_spikes == 20
success, spikes = brush_new.get_spikes()
assert success == True
assert spikes == 20
success, returned_hardness = brush_new.set_hardness(2.0)
assert success == True
assert returned_hardness == 1.0
success, hardness = brush_new.get_hardness()
assert success == True
assert hardness == 1.0
success, returned_aspect_ratio = brush_new.set_aspect_ratio(2000)
assert success == True
assert returned_aspect_ratio == 1000.0
success, aspect_ratio = brush_new.get_aspect_ratio()
assert success == True
assert aspect_ratio == 1000.0
success, returned_angle = brush_new.set_angle(270)
assert success == True
assert returned_angle == 90
success, angle = brush_new.get_angle()
assert success == True
assert angle == 90
"""
Cleanup
"""
success = brush_new.delete()
assert success == True

19
libgimp/test/test_font.py Normal file
View File

@ -0,0 +1,19 @@
"""
Python scripts to test GimpFont class of libgimp API.
See comments about usage and setup in test-resource-class.py
Setup: "Sans-serif" font is selected.
There are few methods on font.
Font has no other getter/setters and is not editable.
Tests of context_set_font and a few other class methods
are in test_resource_class.py
"""
"""
Test a known, stock font "Sans-serif"
"""
font_sans_serif = Gimp.context_get_font()
assert font_sans_serif.get_id() == "Sans-serif"

View File

@ -0,0 +1,314 @@
"""
Python scripts to test GimpGradient class of libgimp API.
See comments about usage and setup in test-resource-class.py
Setup: "FG to BG (RGB)" gradient is selected.
Testing context_get_foo is in test_resource_class.py
"""
"""
Create artifacts needed for testing.
"""
success, foreground_color = Gimp.context_get_foreground()
assert success
success, background_color = Gimp.context_get_background()
assert success
"""
Test a known, stock resource named 'FG to BG (RGB)'
!!! Test numeric literals must change if GIMP developers change the stock gradient.
"""
gradient_FG_BG = Gimp.context_get_gradient()
print(gradient_FG_BG.get_id())
assert gradient_FG_BG.get_id() == 'FG to BG (RGB)'
assert gradient_FG_BG.is_valid() == True
print( gradient_FG_BG.get_number_of_segments() )
assert gradient_FG_BG.get_number_of_segments() == 1
print( gradient_FG_BG.segment_get_blending_function(0) )
success, blending_function = gradient_FG_BG.segment_get_blending_function(0)
assert success
assert blending_function == Gimp.GradientSegmentType.LINEAR
print( gradient_FG_BG.segment_get_coloring_type(0) )
success, coloring_type = gradient_FG_BG.segment_get_coloring_type(0)
assert success
assert coloring_type == Gimp.GradientSegmentColor.RGB
"""
Test stock gradient permissions:
is not editable
setters fail
delete fails
"""
# Stock gradient is not editable
assert not gradient_FG_BG.is_editable()
# Stock gradient is not editable so set color fails and has no effect
# The initial opacity is 100.0 percent
success, left_color, opacity = gradient_FG_BG.segment_get_left_color(0)
assert opacity == 100.0
# Attempt to change opacity to 0 fails
assert not gradient_FG_BG.segment_set_left_color(0, background_color, 0.0)
# opacity is unchanged
success, left_color, opacity = gradient_FG_BG.segment_get_left_color(0)
assert opacity == 100.0
# all other setters return error
assert not gradient_FG_BG.segment_set_right_color(0, background_color, 0.0)
success, position = gradient_FG_BG.segment_set_left_pos(0, 0.0)
assert not success
success, position = gradient_FG_BG.segment_set_right_pos(0, 0.0)
assert not success
success, position = gradient_FG_BG.segment_set_middle_pos(0, 0.0)
assert not success
# There is no setter for a single segment, use a range
assert not gradient_FG_BG.segment_range_set_coloring_type (0, 0, Gimp.GradientSegmentColor.RGB)
assert not gradient_FG_BG.segment_range_set_blending_function(0, 0, Gimp.GradientSegmentType.LINEAR)
# Cannot delete stock gradient
assert not gradient_FG_BG.delete()
"""
Test sampling of gradient.
"""
success, samples = gradient_FG_BG.get_uniform_samples(3, False)
print(samples)
assert success
# Each sample is a color quadruple RGBA
assert len(samples) == 12
# list of 3 sample positions, reverse the gradient
success, samples = gradient_FG_BG.get_custom_samples( [0.0, 0.5, 1.0], True)
assert success
# Each sample is a color quadruple RGBA
assert len(samples) == 12
"""
Test segment methods getters.
"""
success, left_color, opacity = gradient_FG_BG.segment_get_left_color(0)
print(left_color.r, left_color.g, left_color.b, left_color.a)
assert success
# Not supported: assert left_color == foreground_color
# black 0,0,0,1 opacity 1.0
assert left_color.r == 0.0
assert left_color.g == 0.0
assert left_color.b == 0.0
assert left_color.a == 1.0
assert opacity == 100.0
success, right_color, opacity = gradient_FG_BG.segment_get_right_color(0)
print(right_color.r, right_color.g, right_color.b, right_color.a)
assert success
# white 1,1,1,1 opacity 1.0
assert right_color.r == 1.0
assert right_color.g == 1.0
assert right_color.b == 1.0
assert right_color.a == 1.0
assert opacity == 100.0
success, left_pos = gradient_FG_BG.segment_get_left_pos(0)
print(left_pos)
assert left_pos == 0.0
success, right_pos = gradient_FG_BG.segment_get_right_pos(0)
print(right_pos)
assert right_pos == 1.0
success, middle_pos = gradient_FG_BG.segment_get_middle_pos(0)
print(middle_pos)
assert middle_pos == 0.5
success, blending_function = gradient_FG_BG.segment_get_blending_function(0)
assert success
assert blending_function == Gimp.GradientSegmentType.LINEAR
success, coloring_type = gradient_FG_BG.segment_get_coloring_type (0)
assert success
assert coloring_type == Gimp.GradientSegmentColor.RGB
"""
Test new gradient.
"""
gradient_new = Gimp.Gradient.new("New Gradient")
# A new gradient has the requested name.
# Assuming it does not exist already because the tester followed setup correctly
assert gradient_new.get_id() == "New Gradient"
# a new gradient is editable
assert gradient_new.is_editable() == True
# a new gradient has one segment
assert gradient_new.get_number_of_segments() == 1
# attributes of a new gradient are defaulted.
success, left_color, opacity = gradient_FG_BG.segment_get_left_color(0)
print(left_color.r, left_color.g, left_color.b, left_color.a, opacity)
success, right_color, opacity = gradient_FG_BG.segment_get_right_color(0)
print(right_color.r, right_color.g, right_color.b, right_color.a, opacity)
"""
Test segment methods setters.
On the new gradient, which is editable.
"""
# setter succeeds
assert gradient_new.segment_set_left_color(0, background_color, 50.0)
# it changed the color from foreground black to background white
success, left_color, opacity = gradient_new.segment_get_left_color(0)
print(left_color.r, left_color.g, left_color.b, left_color.a)
assert left_color.r == 1.0
assert left_color.g == 1.0
assert left_color.b == 1.0
assert left_color.a == 0.5 # !!! opacity changes the alpha
assert opacity == 50.0
assert gradient_new.segment_set_right_color(0, foreground_color, 50.0)
success, right_color, opacity = gradient_new.segment_get_right_color(0)
print(right_color.r, right_color.g, right_color.b, right_color.a)
assert right_color.r == 0.0
assert right_color.g == 0.0
assert right_color.b == 0.0
assert right_color.a == 0.5
assert opacity == 50.0
success, left_pos = gradient_new.segment_set_left_pos(0, 0.01)
print(left_pos)
assert left_pos == 0.0
success, right_pos = gradient_new.segment_set_right_pos(0, 0.99)
print(right_pos)
assert right_pos == 1.0
success, middle_pos = gradient_new.segment_set_middle_pos(0, 0.49)
print(middle_pos)
assert middle_pos == 0.49
# There is no setter for a single segment, use a range
# Change to a different enum from existing
assert gradient_new.segment_range_set_coloring_type (0, 0, Gimp.GradientSegmentColor.HSV_CW)
success, coloring_type = gradient_new.segment_get_coloring_type (0)
assert success
assert coloring_type == Gimp.GradientSegmentColor.HSV_CW
assert gradient_new.segment_range_set_blending_function(0, 0, Gimp.GradientSegmentType.CURVED)
success, blending_function = gradient_new.segment_get_blending_function (0)
assert success
assert blending_function == Gimp.GradientSegmentType.CURVED
"""
Test segment range methods for splitting and flipping.
!!! Not fully testing the effect, whether segments where shuffled properly.
TODO test a range was flipped by testing for different color types
"""
assert gradient_new.segment_range_split_midpoint(0, 0)
# split one into two
assert gradient_new.get_number_of_segments() == 2
assert gradient_new.segment_range_flip(0, 1)
# flipping does not change count of segments
assert gradient_new.get_number_of_segments() == 2
assert gradient_new.segment_range_replicate(0, 1, 2)
# replicate two segments, first and second.
# replicate each into two, into four total
print( gradient_new.get_number_of_segments() )
assert gradient_new.get_number_of_segments() == 4
assert gradient_new.segment_range_split_midpoint(3, 3)
# We split last one of four, now have 5
assert gradient_new.get_number_of_segments() == 5
assert gradient_new.segment_range_split_midpoint(0, 0)
# We split first one of five, now have 6
assert gradient_new.get_number_of_segments() == 6
assert gradient_new.segment_range_split_uniform(1, 1, 3)
# We split second one of six into 3 parts, now have 8
assert gradient_new.get_number_of_segments() == 8
assert gradient_new.segment_range_delete(6, 6)
# We deleted seventh one of 8, not have seven
assert gradient_new.get_number_of_segments() == 7
# Move segment one left (minus), not compressing
actual_delta = gradient_new.segment_range_move(1, 1, -1.0, False)
print(actual_delta)
assert actual_delta == -0.0637499999
# Moving does not change the count of segments
assert gradient_new.get_number_of_segments() == 7
"""
Test the segment range functions that operate across the range.
TODO test the effect
"""
assert gradient_new.segment_range_redistribute_handles(0, 5)
assert gradient_new.segment_range_blend_colors(1, 4)
assert gradient_new.segment_range_blend_opacity(2, 3)
"""
Test segment methods setters: out of range.
"""
# Segment indexes that do not exist.
assert not gradient_new.segment_set_left_color(9, background_color, 50.0)
# This yields gimp message, so don't always test
# assert not gradient_new.segment_set_left_color(-1, background_color, 50.0)
"""
Test delete gradient
Also cleans up artifacts of testing: the new gradient.
Otherwise it persists and interferes with repeated testing.
"""
gradient_new.delete()
assert not gradient_new.is_valid()
"""
Test that an instance that we created in previous test runs persists.
"""
# TODO fix this by creating it for the next test ession
#gradient_persisted = Gimp.Gradient()
#gradient_persisted.set_property("id", "My Persisted Gradient")
#assert gradient_persisted.get_color_count() == 1
"""
Test invalid gradient
Rare. We do not envision plugins to be constructing Gimp.Gradient using the class constructor.
(Only using the new() method.)
We only envision plugins getting a Gimp.Gradient from a dialog or from Gimp.Context.
Expect error dialog "A plugin is trying to use a resource that is no longer installed."
Commented out because it is tested in test-resource-class.py
and it requires interaction during testing.
"""
#gradient_invalid = Gimp.Gradient() # class constructor in Python
#gradient_invalid.set_property("id", "invalid name")
#assert gradient_invalid.is_editable() == True

View File

@ -0,0 +1,156 @@
"""
Python scripts to test GimpPalette class of libgimp API.
See comments about usage and setup in test-resource-class.py
Setup: "Bears" palette is selected.
Testing context_get_palette is in test_resource_class.py
"""
"""
Create artifacts needed for testing.
"""
success, foreground_color = Gimp.context_get_foreground()
assert success
"""
Ensure setup was done.
"""
if Gimp.context_get_palette().get_id() != "Bears" :
print("\n\n Setup improper: test requires palette Bears selected \n\n")
"""
Test a known, stock palette "Bears"
!!! Test numeric literals must change if the palette is changed.
"""
palette_bears = Gimp.context_get_palette()
assert palette_bears.get_id() == "Bears"
assert palette_bears.get_color_count() == 256
assert palette_bears.get_columns() == 0
colors = palette_bears.get_colors()
assert len(colors) == 256
# color of first entry is as expected
success, color = palette_bears.entry_get_color(0)
assert success
assert color.r == 0.03137254901960784
assert color.g == 0.03137254901960784
assert color.b == 0.03137254901960784
"""
Test permissions on stock palette.
"""
# Stock palette is not editable
assert not palette_bears.is_editable()
# Stock palette cannot set columns
assert not palette_bears.set_columns(4)
# Stock palette cannot add entry
success, index = palette_bears.add_entry("foo", foreground_color)
assert success == False
# Stock palette cannot delete entry
assert not palette_bears.delete_entry(0)
"""
Test new palette.
"""
palette_new = Gimp.Palette.new("Test New Palette")
# A new palette has the requested name.
# Assuming it does not exist already because the tester followed setup correctly
assert palette_new.get_id() == "Test New Palette"
# a new palette is editable
assert palette_new.is_editable() == True
# a new palette has zero colors
assert palette_new.get_color_count() == 0
# a new palette has an empty array of colors
colors = palette_new.get_colors()
assert len(colors) == 0
# a new palette displays with the default count of columns
assert palette_new.get_columns() == 0
# You can set columns even when empty of colors
success = palette_new.set_columns(12)
assert success == True
assert palette_new.get_columns() == 12
# Cannot set columns > 64
# Expect a gimp error dialog "Calling error...out of range"
success = palette_new.set_columns(65)
assert not success
# after out of range, still has the original value
assert palette_new.get_columns() == 12
# Cannot set columns to negative number
# TODO
"""
Test add entry
"""
# You can add entries to a new palette
success, index = palette_new.add_entry("", foreground_color)
assert success == True
# The first index is 0
assert index == 0
# After adding an entry, color count is incremented
assert palette_new.get_color_count() == 1
# The color of the new entry equals what we passed
success, color = palette_new.entry_get_color(0)
assert success == True
assert foreground_color.r == color.r
# You can add the same color twice
success, index = palette_new.add_entry("", foreground_color)
assert success == True
assert index == 1
assert palette_new.get_color_count() == 2
# An added entry for which the provided name was empty string is empty string
# TODO C code seems to suggest that it should be named "Untitled"
success, name = palette_new.entry_get_name(1)
assert success
assert name == ""
"""
Test delete entry
"""
assert palette_new.delete_entry(1) == True
# Delete entry decrements the color count
assert palette_new.get_color_count() == 1
# A deleted entry no longer is gettable
success, name = palette_new.entry_get_name(1)
assert not success
assert name == None
"""
Test that an instance that we created in previous test runs persists.
"""
palette_persisted = Gimp.Palette()
palette_persisted.set_property("id", "Test New Palette")
assert palette_persisted.get_color_count() == 1
"""
Test invalid palette
Rare. We do not envision plugins to be constructing Gimp.Palette using the class constructor.
(Only using the new() method.)
We only envision plugins getting a Gimp.Palette from a dialog or from Gimp.Context.
Expect error dialog "A plugin is trying to use a resource that is no longer installed."
"""
palette_invalid = Gimp.Palette() # class constructor in Python
palette_invalid.set_property("id", "invalid name")
assert palette_invalid.is_editable() == True

View File

@ -0,0 +1,42 @@
"""
Python to test GimpPattern class of libgimp API.
See comments about usage and setup in test-resource-class.py
Paste into the Python Console and expect no exceptions.
Setup: "Pine" Pattern is selected.
Testing some class methods is in test_resource_class.py
Class has no setters.
Object is not editable.
Class has no is_editable() method.
"""
"""
Test a known, stock pattern "Pine"
!!! Test numeric literals must change if the pattern is changed.
"""
pattern_pine = Gimp.context_get_pattern()
assert pattern_pine.get_id() == "Pine"
"""
Test getters
"""
success, width, height, bpp = pattern_pine.get_info()
print( width, height, bpp)
assert success
assert width == 64
assert height == 56
assert bpp == 3
success, width, height, bpp, pixels = pattern_pine.get_pixels()
print( len(pixels) )
assert success
assert width == 64
assert height == 56
assert bpp == 3
assert len(pixels) == 10752
# Not testing the pixels content

View File

@ -351,6 +351,7 @@ gimp_config_param_spec_duplicate (GParamSpec *pspec)
g_strcmp0 (type_name, "GimpLayer") == 0 ||
g_strcmp0 (type_name, "GimpChannel") == 0 ||
g_strcmp0 (type_name, "GimpSelection") == 0 ||
g_strcmp0 (type_name, "GimpBrush") == 0 ||
g_strcmp0 (type_name, "GimpVectors") == 0)
{
copy = g_param_spec_object (name, nick, blurb,

View File

@ -17,6 +17,7 @@ pdb_groups = \
groups/edit.pdb \
groups/file.pdb \
groups/floating_sel.pdb \
groups/font.pdb \
groups/font_select.pdb \
groups/fonts.pdb \
groups/gimp.pdb \

View File

@ -237,6 +237,56 @@ gimp_param_spec_image ("$name",
"$blurb",
$none_ok,
$flags)
CODE
}
elsif ($pdbtype eq 'brush') {
$none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
$pspec = <<CODE;
gimp_param_spec_brush ("$name",
"$nick",
"$blurb",
$none_ok,
$flags)
CODE
}
elsif ($pdbtype eq 'font') {
$none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
$pspec = <<CODE;
gimp_param_spec_font ("$name",
"$nick",
"$blurb",
$none_ok,
$flags)
CODE
}
elsif ($pdbtype eq 'gradient') {
$none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
$pspec = <<CODE;
gimp_param_spec_gradient ("$name",
"$nick",
"$blurb",
$none_ok,
$flags)
CODE
}
elsif ($pdbtype eq 'palette') {
$none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
$pspec = <<CODE;
gimp_param_spec_palette ("$name",
"$nick",
"$blurb",
$none_ok,
$flags)
CODE
}
elsif ($pdbtype eq 'pattern') {
$none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
$pspec = <<CODE;
gimp_param_spec_pattern ("$name",
"$nick",
"$blurb",
$none_ok,
$flags)
CODE
}
elsif ($pdbtype eq 'item') {
@ -793,7 +843,7 @@ CODE
}
else {
my $invoker = "";
$invoker .= ' ' x 2 . "GimpValueArray *return_vals;\n" if scalar @outargs;
$invoker .= &declare_args($proc, $out, 0, qw(inargs));
$invoker .= &declare_args($proc, $out, 1, qw(outargs));

View File

@ -15,6 +15,7 @@
edit
file
floating_sel
font
font_select
fonts
gimp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

68
pdb/groups/font.pdb Normal file
View File

@ -0,0 +1,68 @@
# GIMP - The GNU Image Manipulation Program
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
# 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/>.
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
sub font_id_is_valid {
$blurb = "Whether the ID is a valid reference to installed data.";
$help = "Returns TRUE if this ID is valid.";
&bootchk_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'id',
type => 'string',
non_empty => 1,
no_validate => 1,
desc => 'The font ID' }
);
@outargs = (
{ name => 'valid', type => 'boolean',
desc => 'TRUE if the font ID is valid' }
);
%invoke = (
code => <<'CODE'
{
valid = (gimp_pdb_get_font (gimp, id, error) != NULL);
/* When ID is not valid, NULL is returned and error is set.
* Clear error so GIMP not display error dialog.
*/
g_clear_error (error);
}
CODE
);
}
@headers = qw("core/gimp.h"
"gimppdb-utils.h");
@procs = qw(font_id_is_valid);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Font';
$doc_title = 'gimpfont';
$doc_short_desc = 'Installable object used by text tools.';
$doc_long_desc = 'Installable object used by text tools.';
1;

File diff suppressed because it is too large Load Diff

View File

@ -16,62 +16,63 @@
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
$palette_arg_spec = { name => 'palette', type => 'palette', non_empty => 1,
desc => 'The palette' };
sub palette_new {
$blurb = "Creates a new palette";
$help = "This procedure creates a new, uninitialized palette";
$help = <<'HELP';
Creates a new palette.
The new palette has no color entries.
You must add color entries for a user to choose.
The actual name might be different than the requested name,
when the requested name is already in use.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The requested name of the new palette' }
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The requested name of the new palette' }
);
@outargs = (
{ name => 'actual_name', type => 'string',
desc => 'The actual new palette name' }
${palette_arg_spec}
);
%invoke = (
code => <<'CODE'
{
GimpData *data = gimp_data_factory_data_new (gimp->palette_factory,
palette = (GimpPalette*) gimp_data_factory_data_new (gimp->palette_factory,
context, name);
if (data)
actual_name = g_strdup (gimp_object_get_name (data));
else
success = FALSE;
}
CODE
);
}
sub palette_is_editable {
$blurb = "Tests if palette can be edited";
$blurb = "Whether the palette can be edited";
$help = "Returns TRUE if you have permission to change the palette";
&bill_pdb_misc('2004', '2.4');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' }
${palette_arg_spec}
);
@outargs = (
{ name => 'editable', type => 'boolean',
desc => "TRUE if the palette can be edited" }
{ name => 'editable', type => 'boolean',
desc => "TRUE if the palette can be edited" }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
editable = gimp_data_is_writable (GIMP_DATA (palette));
else
success = FALSE;
editable = gimp_data_is_writable (GIMP_DATA (palette));
}
CODE
);
@ -79,73 +80,107 @@ CODE
sub palette_duplicate {
$blurb = "Duplicates a palette";
$help = "This procedure creates an identical palette by a different name";
$help = "Returns a copy having a different, unique ID.";
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' }
${palette_arg_spec}
);
@outargs = (
{ name => 'copy_name', type => 'string', non_empty => 1,
desc => "The name of the palette's copy" }
{ name => 'palette_copy',
type => 'palette',
desc => "A copy of the palette." }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
{
GimpPalette *palette_copy = (GimpPalette *)
gimp_data_factory_data_duplicate (gimp->palette_factory,
GIMP_DATA (palette));
if (palette_copy)
copy_name = g_strdup (gimp_object_get_name (palette_copy));
else
success = FALSE;
}
else
palette_copy = (GimpPalette *)
gimp_data_factory_data_duplicate (gimp->palette_factory, GIMP_DATA (palette));
/* Assert the copy has a unique name. */
if (!palette_copy)
success = FALSE;
}
CODE
);
}
sub palette_id_is_valid {
$blurb = "Whether the ID is a valid reference to installed data.";
$help = "Returns TRUE if this ID is valid.";
&bootchk_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'id',
type => 'string',
non_empty => 1,
no_validate => 1,
desc => 'The palette ID' }
);
@outargs = (
{ name => 'valid', type => 'boolean',
desc => 'TRUE if the palette ID is valid' }
);
%invoke = (
code => <<'CODE'
{
valid = (gimp_pdb_get_palette (gimp, id, GIMP_PDB_DATA_ACCESS_READ, error) != NULL);
/* When ID is not valid, NULL is returned and error is set.
* Clear error so GIMP not display error dialog.
*/
g_clear_error (error);
}
CODE
);
}
sub palette_rename {
$blurb = "Rename a palette";
$help = "This procedure renames a palette";
$help = <<'HELP';
Renames a palette. The name is the same as the ID.
When the proposed name is already used, GIMP generates a unique name,
which get_id() will return.
Returns a reference to a renamed palette, which you should assign
to the original var or a differently named var.
Any existing references will be invalid.
Resources in plugins are proxies holding an ID,
which can be invalid when the resource is renamed.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'new_name', type => 'string', non_empty => 1,
desc => "The new name of the palette" }
desc => "The requested new name of the palette" }
);
@outargs = (
{ name => 'actual_name', type => 'string',
desc => "The actual new name of the palette" }
);
{ name => 'palette_renamed',
type => 'palette',
desc => "A reference to the renamed palette." }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_RENAME, error);
/* Rename the palette in app. */
gimp_object_set_name (GIMP_OBJECT (palette), new_name);
/* Assert GIMP might have set a name different from new_name. */
if (palette)
{
gimp_object_set_name (GIMP_OBJECT (palette), new_name);
actual_name = g_strdup (gimp_object_get_name (palette));
}
else
success = FALSE;
/* Return a reference.
* The wire protocol will create a new proxy on the plugin side.
* We don't need an alias here, except to make clear
* that we are returning the same real object as passed.
*/
palette_renamed = palette;
}
CODE
);
@ -153,20 +188,20 @@ CODE
sub palette_delete {
$blurb = "Deletes a palette";
$help = "This procedure deletes a palette";
$help = <<'HELP';
Deletes a palette. Returns an error if the palette is not deletable.
Deletes the palette's data. You should not use the palette afterwards.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' }
${palette_arg_spec}
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette && gimp_data_is_deletable (GIMP_DATA (palette)))
success = gimp_data_factory_data_delete (gimp->palette_factory,
GIMP_DATA (palette),
@ -178,101 +213,78 @@ CODE
);
}
sub palette_get_info {
$blurb = 'Retrieve information about the specified palette.';
# When returns a single value, omit: void_ret => 1,
$help = <<'HELP';
This procedure retrieves information about the specified palette. This
includes the name, and the number of colors.
HELP
sub palette_get_color_count {
$blurb = 'Get the count of colors in the palette.';
$help = 'Returns the number of colors in the palette.';
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' }
${palette_arg_spec}
);
@outargs = (
{ name => 'num_colors', type => 'int32', void_ret => 1,
{ name => 'num_colors', type => 'int32',
desc => 'The number of colors in the palette' }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
num_colors = gimp_palette_get_n_colors (palette);
else
success = FALSE;
num_colors = gimp_palette_get_n_colors (palette);
}
CODE
);
}
sub palette_get_colors {
$blurb = 'Gets all colors from the specified palette.';
$blurb = 'Gets colors in the palette.';
$help = <<'HELP';
This procedure retrieves all color entries of the specified palette.
HELP
$help = "Returns an array of colors in the palette.";
&neo_pdb_misc('2006', '2.6');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' }
${palette_arg_spec}
);
@outargs = (
{ name => 'colors', type => 'colorarray',
desc => 'The colors in the palette',
array => { name => 'num_colors',
desc => 'Length of the colors array' } }
desc => 'The colors in the palette',
array => { name => 'num_colors',
desc => 'Length of the colors array' } }
);
%invoke = (
vars => [ 'GimpPalette *palette = NULL' ],
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
GList *list = gimp_palette_get_colors (palette);
gint i;
if (palette)
num_colors = gimp_palette_get_n_colors (palette);
colors = g_new (GimpRGB, num_colors);
for (i = 0; i < num_colors; i++, list = g_list_next (list))
{
GList *list = gimp_palette_get_colors (palette);
gint i;
GimpPaletteEntry *entry = list->data;
num_colors = gimp_palette_get_n_colors (palette);
colors = g_new (GimpRGB, num_colors);
for (i = 0; i < num_colors; i++, list = g_list_next (list))
{
GimpPaletteEntry *entry = list->data;
colors[i] = entry->color;
}
colors[i] = entry->color;
}
else
success = FALSE;
}
CODE
);
}
sub palette_get_columns {
$blurb = "Retrieves the number of columns to use to display this palette";
$help = <<'HELP';
This procedures retrieves the preferred number of columns to use when the
palette is being displayed.
HELP
$blurb = "Gets the number of columns used to display the palette";
$help = "Gets the preferred number of columns to display the palette.";
&neo_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' }
${palette_arg_spec}
);
@outargs = (
@ -283,30 +295,24 @@ HELP
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
if (palette)
num_columns = gimp_palette_get_columns (palette);
else
success = FALSE;
num_columns = gimp_palette_get_columns (palette);
}
CODE
);
}
sub palette_set_columns {
$blurb = "Sets the number of columns to use when displaying the palette";
$blurb = "Sets the number of columns used to display the palette";
$help = <<'HELP';
This procedures controls how many colors are shown per row when the
palette is being displayed. This value can only be changed if the
palette is writable. The maximum allowed value is 64.
Set the number of colors shown per row when the palette is displayed.
Returns an error when the palette is not editable.
The maximum allowed value is 64.
HELP
&neo_pdb_misc('2005', '2.4');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'columns', type => '0 <= int32 <= 64',
desc => "The new number of columns" }
);
@ -314,9 +320,7 @@ HELP
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
gimp_palette_set_columns (palette, columns);
else
success = FALSE;
@ -325,23 +329,28 @@ CODE
);
}
# FIXME null_ok should allow None in Python for name, but fails.
sub palette_add_entry {
$blurb = 'Adds a palette entry to the specified palette.';
$blurb = 'Appends an entry to the palette.';
$help = <<'HELP';
This procedure adds an entry to the specified palette.
It returns an error if the entry palette does not exist.
Appends an entry to the palette.
Neither color nor name must be unique within the palette.
When name is the empty string, this sets the entry name to "Untitled".
Returns the index of the entry.
Returns an error when palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'entry_name', type => 'string', null_ok => 1,
desc => 'The name of the entry' },
desc => 'A name for the entry' },
{ name => 'color', type => 'color',
desc => 'The new entry\'s color color' }
desc => 'The color for the added entry.' }
);
@outargs = (
@ -352,45 +361,44 @@ HELP
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
/* Must check writeable here, because add_entry does not fail when not writeable. */
if (gimp_data_is_writable (GIMP_DATA (palette)))
{
GimpPaletteEntry *entry =
gimp_palette_add_entry (palette, -1, entry_name, &color);
/* -1 for the index means append. */
GimpPaletteEntry *entry = gimp_palette_add_entry (palette, -1, entry_name, &color);
entry_num = gimp_palette_get_entry_position (palette, entry);
}
else
success = FALSE;
{
success = FALSE;
}
}
CODE
);
}
sub palette_delete_entry {
$blurb = 'Deletes a palette entry from the specified palette.';
$blurb = 'Deletes an entry from the palette.';
$help = <<'HELP';
This procedure deletes an entry from the specified palette.
It returns an error if the entry palette does not exist.
Deletes an entry from the palette.
Returns an error if the index is out or range.
Returns an error if the palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The index of the added entry' }
desc => 'The index of the entry to delete' }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
{
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
@ -407,41 +415,33 @@ CODE
}
sub palette_entry_get_color {
$blurb = 'Gets the specified palette entry from the specified palette.';
$blurb = 'Gets the color of an entry in the palette.';
$help = <<'HELP';
This procedure retrieves the color of the zero-based entry specified for the
specified palette. It returns an error if the entry does not exist.
Returns the color of the entry at the given zero-based index into the palette.
Returns an error when the index is out of range.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to retrieve' }
desc => 'The index of the entry to get the color of.' }
);
@outargs = (
{ name => 'color', type => 'color', void_ret => 1,
desc => 'The color requested' }
desc => 'The color at the index.' }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (palette)
{
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (entry)
color = entry->color;
else
success = FALSE;
}
if (entry)
color = entry->color;
else
success = FALSE;
}
@ -450,20 +450,20 @@ CODE
}
sub palette_entry_set_color {
$blurb = 'Sets the specified palette entry in the specified palette.';
$blurb = 'Sets the color of an entry in the palette.';
$help = <<'HELP';
This procedure sets the color of the zero-based entry specified for the
specified palette. It returns an error if the entry does not exist.
Sets the color of the entry at the zero-based index into the palette.
Returns an error when the index is out of range.
Returns an error when the palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to retrieve' },
desc => 'The entry to get' },
{ name => 'color', type => 'color',
desc => 'The new color' }
);
@ -471,9 +471,7 @@ HELP
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
success = gimp_palette_set_entry_color (palette, entry_num, &color);
else
success = FALSE;
@ -483,41 +481,33 @@ CODE
}
sub palette_entry_get_name {
$blurb = 'Gets the specified palette entry from the specified palette.';
$blurb = 'Gets the name of an entry in the palette.';
$help = <<'HELP';
This procedure retrieves the name of the zero-based entry specified for the
specified palette. It returns an error if the entry does not exist.
Gets the name of the entry at the zero-based index into the palette.
Returns an error when the index is out of range.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to retrieve' }
desc => 'The entry to get' }
);
@outargs = (
{ name => 'entry_name', type => 'string', void_ret => 1,
desc => 'The name requested' }
desc => 'The name of the entry.' }
);
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (palette)
{
GimpPaletteEntry *entry = gimp_palette_get_entry (palette, entry_num);
if (entry)
entry_name = g_strdup (entry->name);
else
success = FALSE;
}
if (entry)
entry_name = g_strdup (entry->name);
else
success = FALSE;
}
@ -526,20 +516,20 @@ CODE
}
sub palette_entry_set_name {
$blurb = 'Sets the specified palette entry in the specified palette.';
$blurb = 'Sets the name of an entry in the palette.';
$help = <<'HELP';
This procedure sets the name of the zero-based entry specified for the
specified palette. It returns an error if the entry does not exist.
Sets the name of the entry at the zero-based index into the palette.
Returns an error if the index is out or range.
Returns an error if the palette is not editable.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The palette name' },
${palette_arg_spec},
{ name => 'entry_num', type => 'int32',
desc => 'The entry to retrieve' },
desc => 'The entry to get' },
{ name => 'entry_name', type => 'string', null_ok => 1,
desc => 'The new name' }
);
@ -547,9 +537,7 @@ HELP
%invoke = (
code => <<'CODE'
{
GimpPalette *palette = gimp_pdb_get_palette (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);
if (palette)
if (gimp_data_is_writable (GIMP_DATA (palette)))
success = gimp_palette_set_entry_name (palette, entry_num, entry_name);
else
success = FALSE;
@ -568,10 +556,12 @@ CODE
@procs = qw(palette_new
palette_duplicate
palette_id_is_valid
palette_rename
palette_delete
palette_is_editable
palette_get_info palette_get_colors
palette_get_color_count
palette_get_colors
palette_get_columns palette_set_columns
palette_add_entry palette_delete_entry
palette_entry_get_color palette_entry_set_color
@ -581,7 +571,7 @@ CODE
$desc = 'Palette';
$doc_title = 'gimppalette';
$doc_short_desc = 'Functions operating on a single palette.';
$doc_long_desc = 'Functions operating on a single palette.';
$doc_short_desc = 'Installable object, a small set of colors a user can choose from.';
$doc_long_desc = 'Installable object, a small set of colors a user can choose from.';
1;

View File

@ -16,48 +16,48 @@
# "Perlized" from C source by Manish Singh <yosh@gimp.org>
# The invoke code is compiled on the app side.
# The invoke code must assign to each result var
$pattern_arg_spec = { name => 'pattern', type => 'pattern', non_empty => 1,
desc => 'The pattern' };
sub pattern_get_info {
$blurb = 'Retrieve information about the specified pattern.';
$blurb = 'Gets information about the pattern.';
$help = <<'HELP';
This procedure retrieves information about the specified pattern.
This includes the pattern extents (width and height).
Gets information about the pattern:
the pattern extents (width and height) and bytes per pixel.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The pattern name.' }
${pattern_arg_spec}
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => "The pattern width" },
{ name => 'height', type => 'int32',
desc => "The pattern height" },
{ name => 'bpp', type => 'int32',
desc => "The pattern bpp" }
{ name => 'width', type => 'int32', void_ret => 1,
desc => "The pattern width" },
{ name => 'height', type => 'int32',
desc => "The pattern height" },
{ name => 'bpp', type => 'int32',
desc => "The pattern bpp" }
);
%invoke = (
code => <<'CODE'
{
GimpPattern *pattern = gimp_pdb_get_pattern (gimp, name, error);
const Babl *format;
if (pattern)
{
const Babl *format;
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
}
else
success = FALSE;
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
}
CODE
);
@ -65,58 +65,85 @@ CODE
sub pattern_get_pixels {
$blurb = <<'BLURB';
Retrieve information about the specified pattern (including pixels).
Gets information about the pattern (including pixels).
BLURB
$help = <<'HELP';
This procedure retrieves information about the specified. This
includes the pattern extents (width and height), its bpp and its pixel
data.
Gets information about the pattern:
the pattern extents (width and height), its bpp, and its pixel data.
The pixel data is an array in C or a list in some languages.
HELP
&mitch_pdb_misc('2004', '2.2');
@inargs = (
{ name => 'name', type => 'string', non_empty => 1,
desc => 'The pattern name.' }
${pattern_arg_spec}
);
@outargs = (
{ name => 'width', type => 'int32', void_ret => 1,
desc => "The pattern width" },
{ name => 'height', type => 'int32',
desc => "The pattern height" },
{ name => 'bpp', type => 'int32',
desc => "The pattern bpp" },
{ name => 'color_bytes', type => 'int8array',
desc => 'The pattern data.',
array => { desc => 'Number of pattern bytes' } }
{ name => 'width', type => 'int32', void_ret => 1,
desc => "The pattern width" },
{ name => 'height', type => 'int32',
desc => "The pattern height" },
{ name => 'bpp', type => 'int32',
desc => "The pattern bpp" },
{ name => 'color_bytes', type => 'int8array',
desc => 'The pattern data.',
array => { desc => 'Number of pattern bytes' } }
);
%invoke = (
code => <<'CODE'
{
GimpPattern *pattern = gimp_pdb_get_pattern (gimp, name, error);
if (pattern)
{
const Babl *format;
gpointer data;
const Babl *format;
gpointer data;
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
data = gimp_temp_buf_lock (pattern->mask, format, GEGL_ACCESS_READ);
format = gimp_babl_compat_u8_format (
gimp_temp_buf_get_format (pattern->mask));
data = gimp_temp_buf_lock (pattern->mask, format, GEGL_ACCESS_READ);
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
num_color_bytes = gimp_temp_buf_get_data_size (pattern->mask);
color_bytes = g_memdup2 (data, num_color_bytes);
width = gimp_temp_buf_get_width (pattern->mask);
height = gimp_temp_buf_get_height (pattern->mask);
bpp = babl_format_get_bytes_per_pixel (format);
num_color_bytes = gimp_temp_buf_get_data_size (pattern->mask);
color_bytes = g_memdup2 (data, num_color_bytes);
gimp_temp_buf_unlock (pattern->mask, data);
}
else
success = FALSE;
gimp_temp_buf_unlock (pattern->mask, data);
}
CODE
);
}
sub pattern_id_is_valid {
$blurb = "Whether the ID is a valid reference to installed data.";
$help = "Returns TRUE if this ID is valid.";
&bootchk_pdb_misc('2022', '3.0');
@inargs = (
{ name => 'id',
type => 'string',
non_empty => 1,
no_validate => 1,
desc => 'The pattern ID' }
);
@outargs = (
{ name => 'valid', type => 'boolean',
desc => 'TRUE if the pattern ID is valid' }
);
%invoke = (
code => <<'CODE'
{
/* !!! pattern has one fewer args than other resources. */
valid = (gimp_pdb_get_pattern (gimp, id, error) != NULL);
/* When ID is not valid, NULL is returned and error is set.
* Clear error so GIMP not display error dialog.
*/
g_clear_error (error);
}
CODE
);
@ -132,13 +159,14 @@ CODE
"gimppdb-utils.h");
@procs = qw(pattern_get_info
pattern_get_pixels);
pattern_get_pixels
pattern_id_is_valid);
%exports = (app => [@procs], lib => [@procs]);
$desc = 'Pattern';
$doc_title = 'gimppattern';
$doc_short_desc = 'Functions operating on a single pattern.';
$doc_long_desc = 'Functions operating on a single pattern.';
$doc_short_desc = 'Installable object used by fill and clone tools.';
$doc_long_desc = 'Installable object used by fill and clone tools.';
1;

View File

@ -17,6 +17,7 @@ pdb_names = [
'edit',
'file',
'floating_sel',
'font',
'font_select',
'fonts',
'gimp',

View File

@ -414,7 +414,69 @@ package Gimp::CodeGen::pdb;
get_value_func => '$var = g_value_get_int ($value)',
dup_value_func => '$var = GIMP_VALUES_GET_INT ($value)',
set_value_func => 'g_value_set_int ($value, $var)',
take_value_func => 'g_value_set_int ($value, $var)' }
take_value_func => 'g_value_set_int ($value, $var)' },
# resources
brush => { name => 'BRUSH',
gtype => 'GIMP_TYPE_BRUSH',
type => 'GimpBrush *',
const_type => 'GimpBrush *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = GIMP_VALUES_GET_BRUSH ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/gimpbrush.h") ] },
# !!! include file /app/text/gimpfont.h
font => { name => 'FONT',
gtype => 'GIMP_TYPE_FONT',
type => 'GimpFont *',
const_type => 'GimpFont *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = GIMP_VALUES_GET_FONT ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("text/gimpfont.h") ] },
gradient => { name => 'GRADIENT',
gtype => 'GIMP_TYPE_GRADIENT',
type => 'GimpGradient *',
const_type => 'GimpGradient *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = GIMP_VALUES_GET_GRADIENT ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/gimpgradient.h") ] },
palette => { name => 'PALETTE',
gtype => 'GIMP_TYPE_PALETTE',
type => 'GimpPalette *',
const_type => 'GimpPalette *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = GIMP_VALUES_GET_PALETTE ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/gimppalette.h") ] },
pattern => { name => 'PATTERN',
gtype => 'GIMP_TYPE_PATTERN',
type => 'GimpPattern *',
const_type => 'GimpPattern *',
init_value => 'NULL',
out_annotate => '(transfer full)',
get_value_func => '$var = g_value_get_object ($value)',
dup_value_func => '$var = GIMP_VALUES_GET_PATTERN ($value)',
set_value_func => 'g_value_set_object ($value, $var)',
take_value_func => 'g_value_set_object ($value, $var)',
headers => [ qw("core/gimppattern.h") ] }
);
# Split out the parts of an arg constraint

View File

@ -69,6 +69,10 @@ sub bill_pdb_misc {
contrib_pdb_misc('Bill Skaggs', 'weskaggs@primate.ucdavis.edu', @_);
}
sub bootchk_pdb_misc {
contrib_pdb_misc('Lloyd Konneker', '', @_);
}
sub david_pdb_misc {
contrib_pdb_misc('David Gowers', '', @_);
}

View File

@ -446,7 +446,8 @@ get_samples_gradient (GimpDrawable *drawable)
static gdouble *
get_samples_palette (GimpDrawable *drawable)
{
gchar *palette_name;
GimpPalette *palette;
GimpRGB color_sample;
gdouble *d_samples, *d_samp;
gboolean is_rgb;
@ -455,8 +456,8 @@ get_samples_palette (GimpDrawable *drawable)
gint nb_color_chan, nb_chan, i;
const Babl *format;
palette_name = gimp_context_get_palette ();
gimp_palette_get_info (palette_name, &num_colors);
palette = gimp_context_get_palette ();
num_colors = gimp_palette_get_color_count (palette);
is_rgb = gimp_drawable_is_rgb (drawable);
@ -472,12 +473,12 @@ get_samples_palette (GimpDrawable *drawable)
d_samp = &d_samples[i * nb_chan];
pal_entry = CLAMP ((int)(i * factor), 0, num_colors - 1);
gimp_palette_entry_get_color (palette_name, pal_entry, &color_sample);
gimp_palette_entry_get_color (palette, pal_entry, &color_sample);
gimp_rgb_get_pixel (&color_sample,
format,
d_samp);
}
g_free (palette_name);
g_free (palette);
return d_samples;
}

View File

@ -652,7 +652,7 @@ gfig_read_gimp_style (Style *style,
gimp_brush_get_info (style->brush_name,
&style->brush_width, &style->brush_height,
&dummy, &dummy);
gimp_brush_get_spacing (style->brush_name, &style->brush_spacing);
style->brush_spacing = gimp_brush_get_spacing (style->brush_name);
style->gradient = gimp_context_get_gradient ();
style->pattern = gimp_context_get_pattern ();

View File

@ -15,6 +15,12 @@ plugins = [
{ 'name': 'spyro-plus' },
]
if not stable
plugins += [
{ 'name': 'test-dialog' },
]
endif
subdir('python-console')
foreach plugin : plugins

View File

@ -0,0 +1,133 @@
#!/usr/bin/env python3
#
# 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('Gimp', '3.0')
from gi.repository import Gimp
gi.require_version('GimpUi', '3.0')
from gi.repository import GimpUi
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio
import time
import sys
'''
A Python plugin.
Tests GimpProcedureDialog.
Temporarily, just testing widgets for subclasses of GimpResource.
Temporarily, just testing Brush subclass of Resource.
FUTURE: For all the parameter types.
Formerly PF_ constants, now all parameters for which GimpParamSpecs exist.
Not localized, no i18n
'''
def process_args(brush):
'''
Test the args are sane.
'''
assert brush is not None
assert isinstance(brush, Gimp.Brush)
assert brush.get_id() is not None
print( "Brush id is:", brush.get_id())
return
def test_dialog(procedure, run_mode, image, n_drawables, drawables, args, data):
'''
Just a standard shell for a plugin.
'''
config = procedure.create_config()
config.begin_run(image, run_mode, args)
if run_mode == Gimp.RunMode.INTERACTIVE:
GimpUi.init('python-fu-test-dialog')
dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config)
dialog.fill(None)
if not dialog.run():
dialog.destroy()
config.end_run(Gimp.PDBStatusType.CANCEL)
return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, GLib.Error())
else:
dialog.destroy()
brush = config.get_property('brush')
# opacity = config.get_property('opacity')
Gimp.context_push()
image.undo_group_start()
process_args(brush)
Gimp.displays_flush()
image.undo_group_end()
Gimp.context_pop()
config.end_run(Gimp.PDBStatusType.SUCCESS)
return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
class TestDialogPlugin (Gimp.PlugIn):
## Parameters ##
__gproperties__ = {
}
# See comments about this in foggify.py, from which we borrowed
brush = GObject.Property(type =Gimp.Brush,
# no default?
nick ="Brush",
blurb="Brush")
# FUTURE all other Gimp classes that have GimpParamSpecs
## GimpPlugIn virtual methods ##
def do_set_i18n(self, procname):
return True, 'gimp30-python', None
def do_query_procedures(self):
return [ 'python-fu-test-dialog' ]
def do_create_procedure(self, name):
procedure = Gimp.ImageProcedure.new(self, name,
Gimp.PDBProcType.PLUGIN,
test_dialog, None)
procedure.set_image_types("*");
procedure.set_sensitivity_mask (Gimp.ProcedureSensitivityMask.DRAWABLE |
Gimp.ProcedureSensitivityMask.DRAWABLES)
procedure.set_documentation ("Test dialog",
"Test dialog",
name)
procedure.set_menu_label("Test dialog...")
procedure.set_attribution("Lloyd Konneker",
"Lloyd Konneker",
"2022")
# Top level menu "Test"
procedure.add_menu_path ("<Image>/Test")
procedure.add_argument_from_property(self, "brush")
return procedure
Gimp.main(TestDialogPlugin.__gtype__, sys.argv)

View File

@ -1215,6 +1215,27 @@ script_fu_marshal_procedure_call (scheme *sc,
"Status is for return types, not arguments",
sc->vptr->pair_car (a));
}
else if (GIMP_VALUE_HOLDS_RESOURCE (&value))
{
GType type = G_VALUE_TYPE (&value);
if (! sc->vptr->is_string (sc->vptr->pair_car (a)))
return script_type_error (sc, "string", i, proc_name);
else
{
/* Create new instance of a resource object. */
GimpResource *resource;
gchar* id = sc->vptr->string_value (sc->vptr->pair_car (a));
resource = g_object_new (type, NULL);
g_object_set (resource, "id", id, NULL);
/* Assert set property copies the string. */
g_value_set_object (&value, resource);
/* Assert set_object refs the resource. */
}
}
else
{
g_snprintf (error_str, sizeof (error_str),
@ -1310,7 +1331,11 @@ script_fu_marshal_procedure_call (scheme *sc,
g_debug ("Return value %d is type %s", i+1, G_VALUE_TYPE_NAME (value));
/* Order is important. GFile before GIMP objects. */
/* Order is important.
* GFile before other objects.
* GIMP resource objects before GIMP Image, Drawable, etc. objects.
* Alternatively, more specific tests.
*/
if (G_VALUE_TYPE (value) == G_TYPE_FILE)
{
gchar *parsed_filepath = marshal_returned_gfile_to_string (value);
@ -1329,11 +1354,37 @@ script_fu_marshal_procedure_call (scheme *sc,
}
/* Ensure return_val holds a string, possibly empty. */
}
else if (GIMP_VALUE_HOLDS_RESOURCE (value))
{
/* ScriptFu represents resource objects by ther unique string ID's. */
GObject *object = g_value_get_object (value);
gchar *id = "";
/* expect a GIMP opaque object having an "id" property */
if (object)
{
g_object_get (object, "id", &id, NULL);
g_object_unref (object);
}
/* id is empty when the gvalue had no GObject*,
* or the referenced object had no property "id".
* This can be an undetected fault in the called procedure.
* It is not necessarily an error in the script.
*/
if (strlen(id) == 0)
g_warning("PDB procedure returned NULL GIMP object or non-GIMP object.");
g_debug ("PDB procedure returned object ID: %s", id);
return_val = sc->vptr->cons (sc, sc->vptr->mk_string (sc, id), return_val);
}
else if (G_VALUE_HOLDS_OBJECT (value))
{
/* G_VALUE_HOLDS_OBJECT only ensures value derives from GObject.
* Could be a GIMP or a GLib type.
* Here we handle GIMP types, which all have an id property.
* Resources have a string ID and Images and Drawables etc. have an int ID.
*/
GObject *object = g_value_get_object (value);
gint id = -1;

View File

@ -374,14 +374,13 @@ script_fu_arg_get_param_spec (SFArg *arg,
break;
case SF_BRUSH:
/* FUTURE: brush object has more fields.
* ?? Implement gimp_param_spec_brush
*/
pspec = g_param_spec_string (name,
nick,
arg->label,
arg->default_value.sfa_brush.name,
G_PARAM_READWRITE);
/* FIXME: SF-BRUSH will not have opacity, etc. instead gimp_brush_select will choose only brush. */
/* FIXME: font, etc. are resource types. Brush is just the test for WIP. */
pspec = gimp_param_spec_brush (name,
nick,
arg->label,
FALSE, /* none OK */
G_PARAM_READWRITE | GIMP_PARAM_NO_VALIDATE);
break;
case SF_ADJUSTMENT:
@ -569,10 +568,22 @@ script_fu_arg_append_repr_from_gvalue (SFArg *arg,
case SF_PALETTE:
case SF_PATTERN:
case SF_GRADIENT:
case SF_BRUSH:
g_string_append_printf (result_string, "\"%s\"", g_value_get_string (gvalue));
break;
case SF_BRUSH:
{
/* The GValue is a GObject of type GimpBrush having property "id" */
GimpBrush *brush;
gchar *brush_name;
brush = g_value_get_object (gvalue);
g_object_get (brush, "id", &brush_name, NULL);
g_string_append_printf (result_string, "\"%s\"", brush_name);
}
break;
case SF_OPTION:
append_int_repr_from_gvalue (result_string, gvalue);
break;

View File

@ -0,0 +1,161 @@
#!/usr/bin/env gimp-script-fu-interpreter-3.0
; A script that tests resource classes in GIMP
; Tests the marshalling of parameters and return values in ScriptFu
;
; Setup: copy this file w/ executable permission, and its parent dir to /plug-ins
; Example: to ~/.gimp-2.99/plug-ins/always-fail/always-fail.scm
; Delete .config/GIMP so that resources are in a standard state.
; Expect various resource names in the console
; Expect no "Fail" in the console
(define (script-fu-test-resource-class)
(define (expect expression
expected-value )
; use equal?, don't use eq?
(if (equal? expression expected-value)
#t
(gimp-message "Fail")
)
)
; redirect messages to the console
(gimp-message-set-handler 1)
(let* (
; Test as a return value
; These calls return a list with one element, use car
(brush (car (gimp-context-get-brush)))
(font (car (gimp-context-get-font)))
(gradient (car (gimp-context-get-gradient)))
(palette (car (gimp-context-get-palette)))
(pattern (car (gimp-context-get-pattern)))
; font and pattern cannot be new(), duplicate(), delete()
; new() methods
(brushnew (car (gimp-brush-new "Brush New")))
(gradientnew (car (gimp-gradient-new "Gradient New")))
(palettenew (car (gimp-palette-new "Palette New")))
; copy() methods
; copy method is named "duplicate"
; Takes an existing brush and a desired name
(brushcopy (car (gimp-brush-duplicate brushnew "brushcopy")))
(gradientcopy (car (gimp-gradient-duplicate gradientnew "gradientcopy")))
(palettecopy (car (gimp-palette-duplicate palettenew "palettecopy")))
; See below, we test rename later
)
; write names to console
(gimp-message brush)
(gimp-message font)
(gimp-message gradient)
(gimp-message palette)
(gimp-message pattern)
(gimp-message brushnew)
(gimp-message gradientnew)
(gimp-message palettenew)
(gimp-message brushcopy)
(gimp-message gradientcopy)
(gimp-message palettecopy)
; Note equal? works for strings, but eq? and eqv? do not
(gimp-message "Expect resources from context have de novo installed GIMP names")
(expect (equal? brush "2. Hardness 050") #t)
(expect (equal? font "Sans-serif") #t)
(expect (equal? gradient "FG to BG (RGB)") #t)
(expect (equal? palette "Color History") #t)
(expect (equal? pattern "Pine") #t)
(gimp-message "Expect new resource names are the names given when created")
(expect (equal? brushnew "Brush New") #t)
(expect (equal? gradientnew "Gradient New") #t)
(expect (equal? palettenew "Palette New") #t)
(gimp-message "Expect copied resources have names given when created")
; !!! TODO GIMP appends " copy" and does not use the given name
; which contradicts the docs for the procedure
(expect (equal? brushcopy "Brush New copy") #t)
(expect (equal? gradientcopy "Gradient New copy") #t)
(expect (equal? palettecopy "Palette New copy") #t)
; rename() methods
; Returns new resource proxy, having possibly different name than requested
; ScriptFu marshals to a string
; !!! Must assign it to the same var,
; else the var becomes an invalid reference since it has the old name
(set! brushcopy (car (gimp-brush-rename brushcopy "Brush Copy Renamed")))
(set! gradientcopy (car (gimp-gradient-rename gradientcopy "Gradient Copy Renamed")))
(set! palettecopy (car (gimp-palette-rename palettecopy "Palette Copy Renamed")))
; write renames to console
(gimp-message brushcopy)
(gimp-message gradientcopy)
(gimp-message palettecopy)
(gimp-message "Expect renamed have new names")
(expect (equal? brushcopy "Brush Copy Renamed") #t)
(expect (equal? gradientcopy "Gradient Copy Renamed") #t)
(expect (equal? palettecopy "Palette Copy Renamed") #t)
(gimp-message "Expect class method id_is_valid of the GimpResource class")
; the class method takes a string.
; ScriptFu already has a string var, and marshalling is trivial
; For now, returns (1), not #t
(expect (car (gimp-brush-id-is-valid brush)) 1)
(expect (car (gimp-font-id-is-valid font)) 1)
(expect (car (gimp-gradient-id-is-valid gradient)) 1)
(expect (car (gimp-palette-id-is-valid palette)) 1)
(expect (car (gimp-pattern-id-is-valid pattern)) 1)
(gimp-message "Expect class method id_is_valid for invalid name")
; Expect false, but no error dialog from GIMP
; Returns (0), not #f
(expect (car (gimp-brush-id-is-valid "invalid_name")) 0)
(expect (car (gimp-font-id-is-valid "invalid_name")) 0)
(expect (car (gimp-gradient-id-is-valid "invalid_name")) 0)
(expect (car (gimp-palette-id-is-valid "invalid_name")) 0)
(expect (car (gimp-pattern-id-is-valid "invalid_name")) 0)
(gimp-message "Expect as a parameter to context works")
; Pass each resource class instance back to Gimp
(gimp-context-set-brush brush)
(gimp-context-set-font font)
(gimp-context-set-gradient gradient)
(gimp-context-set-palette palette)
(gimp-context-set-pattern pattern)
(gimp-message "Expect delete methods work without error")
(gimp-brush-delete brushnew)
(gimp-gradient-delete gradientnew)
(gimp-palette-delete palettenew)
(gimp-message "Expect var holding deleted resource is still defined, but is invalid reference")
; Returns (0), not #f
(expect (car (gimp-brush-id-is-valid brushnew)) 0)
(expect (car (gimp-gradient-id-is-valid gradientnew)) 0)
(expect (car (gimp-palette-id-is-valid palettenew)) 0)
; We don't test the specialized methods of the classes here, see elsewhere
)
)
(script-fu-register "script-fu-test-resource-class"
"Test resource classes of Gimp"
"Expect no errors in the console"
"lkk"
"lkk"
"2022"
"" ; requires no image
; no arguments or dialog
)
(script-fu-menu-register "script-fu-test-resource-class" "<Image>/Test")