2.99 ScriptFu: add custom widgets to GimpProcedureDialog
For version 3 scripts, using script-fu-register-filter Widgets for SF-OPTION and SF-DIRNAME Fixes #9992 Test case is Sphere v3. Note that SF-VECTORS is still not supported, until there is a VectorsChooser widget in libgimp. A step towards deprecating old-style scripts using script-fu-register, and deleting script-fu-interface, the duplicate dialog for SF. But we still need to change or replace script-fu-register (for non-filter plugins) to use GimpProcedureDialog.
This commit is contained in:
parent
978a795eb7
commit
ab626e79ec
7 changed files with 247 additions and 7 deletions
|
|
@ -21,6 +21,7 @@ libscriptfu_sources = [
|
|||
'script-fu-dialog.c',
|
||||
'script-fu-run-func.c',
|
||||
'script-fu-command.c',
|
||||
'script-fu-widgets-custom.c',
|
||||
]
|
||||
|
||||
# !! just "library(...)" which means shared versus static depends on configuration of project.
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ void
|
|||
script_fu_arg_free (SFArg *arg)
|
||||
{
|
||||
g_free (arg->label);
|
||||
g_free (arg->property_name);
|
||||
|
||||
switch (arg->type)
|
||||
{
|
||||
|
|
@ -386,6 +387,10 @@ script_fu_arg_get_param_spec (SFArg *arg,
|
|||
/* FUTURE: Default not now appear in PDB browser, but appears in widgets? */
|
||||
break;
|
||||
|
||||
/* Not necessary to have a more specific pspec:
|
||||
* pspec = gimp_param_spec_config_path (...GIMP_TYPE_CONFIG_PATH...)
|
||||
*/
|
||||
|
||||
case SF_ENUM:
|
||||
/* history is the last used value AND the default. */
|
||||
pspec = g_param_spec_enum (name,
|
||||
|
|
@ -695,6 +700,8 @@ script_fu_arg_reset_name_generator (void)
|
|||
* The returned string is owned by the generator, a constant.
|
||||
* The caller need not copy it,
|
||||
* but usually does by creating a GParamSpec.
|
||||
*
|
||||
* As a side effect, a copy of the string is kept in arg->property_name.
|
||||
*/
|
||||
void
|
||||
script_fu_arg_generate_name_and_nick (SFArg *arg,
|
||||
|
|
@ -803,6 +810,9 @@ script_fu_arg_generate_name_and_nick (SFArg *arg,
|
|||
|
||||
arg_count[arg->type]++;
|
||||
|
||||
/* Side effect: remember the generated name. */
|
||||
arg->property_name = g_strdup (numbered_name);
|
||||
|
||||
*returned_name = numbered_name;
|
||||
|
||||
/* nick is what the script author said describes the arg */
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "script-fu-command.h"
|
||||
|
||||
#include "script-fu-dialog.h"
|
||||
#include "script-fu-widgets-custom.h"
|
||||
|
||||
|
||||
/* An informal class that shows a dialog for a script then runs the script.
|
||||
|
|
@ -159,13 +160,11 @@ script_fu_dialog_run (GimpProcedure *procedure,
|
|||
script_fu_script_get_title (script));
|
||||
/* dialog has no widgets except standard buttons. */
|
||||
|
||||
/* It is possible to create custom widget where the provided widget is not adequate.
|
||||
* Then gimp_procedure_dialog_fill_list will create the rest.
|
||||
* For now, the provided widgets should be adequate.
|
||||
*/
|
||||
/* Create custom widget where the stock widget is not adequate. */
|
||||
script_fu_widgets_custom_add (dialog, script);
|
||||
|
||||
/* NULL means create widgets for all properties of the procedure
|
||||
* that we have not already created widgets for.
|
||||
* that we have not already created custom widgets for.
|
||||
*/
|
||||
gimp_procedure_dialog_fill_list (dialog, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ typedef union
|
|||
typedef struct
|
||||
{
|
||||
SFArgType type;
|
||||
gchar *label;
|
||||
gchar *label; /* label on widget in dialog. Not unique. */
|
||||
gchar *property_name; /* name of property of Procedure. Unique. */
|
||||
SFArgValue default_value;
|
||||
SFArgValue value;
|
||||
} SFArg;
|
||||
|
|
|
|||
200
plug-ins/script-fu/libscriptfu/script-fu-widgets-custom.c
Normal file
200
plug-ins/script-fu/libscriptfu/script-fu-widgets-custom.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* Copyright (C) 2024 Lloyd Konneker
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libgimp/gimpui.h>
|
||||
|
||||
#include "script-fu-types.h"
|
||||
#include "script-fu-widgets-custom.h"
|
||||
|
||||
/* Widgets in GimpProcedureDialog *custom* to ScriptFu.
|
||||
*
|
||||
* GimpProcedureDialog provides stock widgets
|
||||
* based on the type of a procedure argument.
|
||||
* A custom widget is the same kind of widget as stock, but specialized.
|
||||
*
|
||||
* Both stock and custom widgets are keyed to a property name
|
||||
* of the GimpProcedure for the script.
|
||||
* You add custom widgets, then call gimp_procedure_dialog_fill_list()
|
||||
* which adds a stock widget for any property name not having a custom widget.
|
||||
*
|
||||
* FUTURE: implement these in GimpProcedureDialog.
|
||||
* That can't be done now because GParamSpecs are limited
|
||||
* in the types they can describe.
|
||||
* E.G. SF-OPTION describes an enumerated type
|
||||
* that can't be described completely in a GParamSpec.
|
||||
* E.G. property type GFile is a general type
|
||||
* whose subtypes: existing-file, existing-dir, or file-to-save
|
||||
* can't be described in a GParamSpec.
|
||||
*
|
||||
* Most SFArg types are supported by stock widgets.
|
||||
*
|
||||
* SF-FILENAME is stock.
|
||||
* For property of type G_TYPE_FILE.
|
||||
* A GtkFileChooser in the mode for user to open a existing file.
|
||||
*
|
||||
* SF-DIRNAME is custom.
|
||||
* Also a GtkFileChooser but in mode for user to choose a directory.
|
||||
*
|
||||
* FUTURE:
|
||||
* SF-SAVE-FILENAME is custom.
|
||||
* Also a GtkFileChooser but in mode for user to save a file
|
||||
* (choose a file to replace, or enter filename and choose a directory.)
|
||||
*
|
||||
* SF-OPTION is custom.
|
||||
* Is an int combo box widget, for an enumeration defined by the script
|
||||
* (versus SF-ENUM for enums defined by GIMP.)
|
||||
* Note SF-OPTION does not create symbols in the interpreter.
|
||||
* The script itself, and all other plugins, must use integer literals
|
||||
* to denote values.
|
||||
*/
|
||||
|
||||
/* Does SFArg type need custom widget? */
|
||||
static gboolean
|
||||
sf_arg_type_is_custom (SFScript *script,
|
||||
guint arg_index)
|
||||
{
|
||||
switch (script->args[arg_index].type)
|
||||
{
|
||||
case SF_DIRNAME:
|
||||
case SF_OPTION:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns new GtkListStore from SFArg declaration.
|
||||
* Transfers ownership of the allocated, returned store.
|
||||
* Ownership transfers to a dialog, which frees it on dialog destroy.
|
||||
*
|
||||
* Returned value is never NULL.
|
||||
* Returned store can be empty if the declaration of the arg is non-sensical.
|
||||
*/
|
||||
static GtkListStore *
|
||||
sf_widget_custom_new_int_store (SFArg *arg)
|
||||
{
|
||||
GtkListStore *result;
|
||||
GSList *list;
|
||||
guint counter = 0; /* SF enumerations start at 0. */
|
||||
|
||||
/* Create empty store. */
|
||||
result = g_object_new (GIMP_TYPE_INT_STORE, NULL);
|
||||
|
||||
/* Iterate over list of names of enumerated values,
|
||||
* appending each to store having value equal to the iteration index.
|
||||
*
|
||||
* ScriptFu does NOT define constant Scheme symbols in the interpreter;
|
||||
* the names of enumerated values are not available to the script,
|
||||
* which must use integer literals or (define other symbols for the values.)
|
||||
*/
|
||||
for (list = arg->default_value.sfa_option.list;
|
||||
list;
|
||||
list = g_slist_next (list))
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_append (result, &iter);
|
||||
gtk_list_store_set (result, &iter,
|
||||
GIMP_INT_STORE_VALUE, counter,
|
||||
GIMP_INT_STORE_LABEL, list->data,
|
||||
-1);
|
||||
counter++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Adds widget for arg of type SF-OPTION to the dialog.
|
||||
* Widget is a combobox widget.
|
||||
* Specializes the widget by a custom store i.e. model
|
||||
* derived from the arg's declaration.
|
||||
*/
|
||||
static void
|
||||
sf_widget_custom_option (GimpProcedureDialog *dialog,
|
||||
SFArg *arg)
|
||||
{
|
||||
GtkListStore *store;
|
||||
|
||||
store = sf_widget_custom_new_int_store (arg);
|
||||
gimp_procedure_dialog_get_int_combo (dialog,
|
||||
arg->property_name,
|
||||
GIMP_INT_STORE (store));
|
||||
}
|
||||
|
||||
/* Adds widget for arg of type SF-DIRNAME to the dialog.
|
||||
* Widget is a GtkFileChooserButton.
|
||||
* Specializes the widget to be in mode for user to choose a directory.
|
||||
*
|
||||
* Note that this is implemented by gtk_file_chooser_button,
|
||||
* which does not support ACTION_SAVE, and which becomes obsolete in Gtk4.
|
||||
* Thus, we don't have SF-SAVE-FILENAME.
|
||||
* To offer save, a script must use two widgets:
|
||||
* SF-STRING for user to name a file to save,
|
||||
* and SF-DIRNAME for user to choose directory to save to.
|
||||
*/
|
||||
static void
|
||||
sf_widget_custom_dirname (GimpProcedureDialog *dialog,
|
||||
SFArg *arg)
|
||||
{
|
||||
gimp_procedure_dialog_get_file_chooser (dialog,
|
||||
arg->property_name,
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
||||
}
|
||||
|
||||
/* Add a custom widget for a script's arg to the script's dialog.
|
||||
* Does nothing when the type of the arg does not need a custom widget.
|
||||
*
|
||||
* Widget is associated with the arg's property, by name of the property.
|
||||
* The arg's property is a property of the Procedure.
|
||||
* The widget will be positioned in the dialog by order of property.
|
||||
*/
|
||||
static void
|
||||
sf_widget_custom_add_to_dialog (GimpProcedureDialog *dialog,
|
||||
SFArg *arg)
|
||||
{
|
||||
/* Handles same cases as sf_arg_type_is_custom() */
|
||||
switch (arg->type)
|
||||
{
|
||||
case SF_OPTION:
|
||||
sf_widget_custom_option (dialog, arg);
|
||||
break;
|
||||
case SF_DIRNAME:
|
||||
sf_widget_custom_dirname (dialog, arg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add custom widgets to dialog, for certain type of args of script. */
|
||||
void
|
||||
script_fu_widgets_custom_add (GimpProcedureDialog *dialog,
|
||||
SFScript *script)
|
||||
{
|
||||
for (int arg_index=0; arg_index < script->n_args; arg_index++)
|
||||
{
|
||||
if (sf_arg_type_is_custom (script, arg_index))
|
||||
{
|
||||
sf_widget_custom_add_to_dialog (dialog, &script->args[arg_index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
plug-ins/script-fu/libscriptfu/script-fu-widgets-custom.h
Normal file
26
plug-ins/script-fu/libscriptfu/script-fu-widgets-custom.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* Copyright (C) 2024 Lloyd Konneker
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __SCRIPT_FU_WIDGETS_CUSTOM_H__
|
||||
#define __SCRIPT_FU_WIDGETS_CUSTOM_H__
|
||||
|
||||
void script_fu_widgets_custom_add (GimpProcedureDialog *dialog,
|
||||
SFScript *script);
|
||||
|
||||
#endif /* __SCRIPT_FU_WIDGETS_CUSTOM_H__ */
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
size
|
||||
unused-palette
|
||||
unused-filename
|
||||
unused-orientation
|
||||
orientation
|
||||
unused-interpolation
|
||||
unused-dirname
|
||||
unused-image
|
||||
|
|
@ -123,6 +123,9 @@
|
|||
size
|
||||
font)))
|
||||
|
||||
(if (= orientation 1)
|
||||
(gimp-image-rotate img ROTATE-DEGREES90))
|
||||
|
||||
(gimp-image-undo-enable img)
|
||||
(gimp-display-new img)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue