Initial checkin of Pika from heckimp

This commit is contained in:
2023-09-25 15:35:21 -07:00
commit 891e999216
6761 changed files with 5240685 additions and 0 deletions

33
app/propgui/meson.build Normal file
View File

@ -0,0 +1,33 @@
libapppropgui_sources = [
'pikapropgui-channel-mixer.c',
'pikapropgui-color-balance.c',
'pikapropgui-color-rotate.c',
'pikapropgui-color-to-alpha.c',
'pikapropgui-convolution-matrix.c',
'pikapropgui-diffraction-patterns.c',
'pikapropgui-eval.c',
'pikapropgui-focus-blur.c',
'pikapropgui-generic.c',
'pikapropgui-hue-saturation.c',
'pikapropgui-motion-blur-circular.c',
'pikapropgui-motion-blur-linear.c',
'pikapropgui-motion-blur-zoom.c',
'pikapropgui-newsprint.c',
'pikapropgui-panorama-projection.c',
'pikapropgui-recursive-transform.c',
'pikapropgui-shadows-highlights.c',
'pikapropgui-spiral.c',
'pikapropgui-supernova.c',
'pikapropgui-utils.c',
'pikapropgui-vignette.c',
'pikapropgui.c',
]
libapppropgui = static_library('apppropgui',
libapppropgui_sources,
include_directories: [ rootInclude, rootAppInclude, ],
c_args: '-DG_LOG_DOMAIN="Pika-PropGUI"',
dependencies: [
gegl, gtk3,
],
)

View File

@ -0,0 +1,135 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-channel-mixer.c
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-channel-mixer.h"
#include "pika-intl.h"
GtkWidget *
_pika_prop_gui_new_channel_mixer (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *checkbox;
GtkWidget *scale;
const gchar *label;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
frame = pika_frame_new (_("Red channel"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
scale = pika_prop_widget_new (config, "rr-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "rg-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "rb-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
frame = pika_frame_new (_("Green channel"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
scale = pika_prop_widget_new (config, "gr-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "gg-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "gb-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
frame = pika_frame_new (_("Blue channel"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
scale = pika_prop_widget_new (config, "br-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "bg-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "bb-gain",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
checkbox = pika_prop_widget_new (config, "preserve-luminosity",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (main_vbox), checkbox, FALSE, FALSE, 0);
return main_vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-channel-mixer.h
*
* 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 __PIKA_PROP_GUI_CHANNEL_MIXER_H__
#define __PIKA_PROP_GUI_CHANNEL_MIXER_H__
GtkWidget *
_pika_prop_gui_new_channel_mixer (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_CHANNEL_MIXER_H__ */

View File

@ -0,0 +1,147 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-color-balance.c
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "operations/pikacolorbalanceconfig.h"
#include "core/pikacontext.h"
#include "widgets/pikapropwidgets.h"
#include "pikapropgui.h"
#include "pikapropgui-color-balance.h"
#include "pika-intl.h"
static void
create_levels_scale (GObject *config,
const gchar *property_name,
const gchar *left,
const gchar *right,
GtkWidget *grid,
gint col)
{
GtkWidget *label;
GtkWidget *scale;
label = gtk_label_new (left);
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
gtk_grid_attach (GTK_GRID (grid), label, 0, col, 1, 1);
gtk_widget_show (label);
scale = pika_prop_spin_scale_new (config, property_name, 0.01, 0.1, 0);
pika_spin_scale_set_label (PIKA_SPIN_SCALE (scale), NULL);
pika_prop_widget_set_factor (scale, 100.0, 1.0, 10.0, 1);
gtk_widget_set_hexpand (scale, TRUE);
gtk_grid_attach (GTK_GRID (grid), scale, 1, col, 1, 1);
label = gtk_label_new (right);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_grid_attach (GTK_GRID (grid), label, 2, col, 1, 1);
gtk_widget_show (label);
}
GtkWidget *
_pika_prop_gui_new_color_balance (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *grid;
GtkWidget *button;
GtkWidget *frame;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
frame = pika_prop_enum_radio_frame_new (config, "range",
_("Select Range to Adjust"),
0, 0);
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
frame = pika_frame_new (_("Adjust Color Levels"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* The grid containing sliders */
grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
gtk_widget_show (grid);
create_levels_scale (config, "cyan-red",
_("Cyan"), _("Red"),
grid, 0);
create_levels_scale (config, "magenta-green",
_("Magenta"), _("Green"),
grid, 1);
create_levels_scale (config, "yellow-blue",
_("Yellow"), _("Blue"),
grid, 2);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
button = gtk_button_new_with_mnemonic (_("R_eset Range"));
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (pika_color_balance_config_reset_range),
config);
button = pika_prop_check_button_new (config,
"preserve-luminosity",
_("Preserve _luminosity"));
gtk_box_pack_end (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
return main_vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-color-balance.h
*
* 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 __PIKA_PROP_GUI_COLOR_BALANCE_H__
#define __PIKA_PROP_GUI_COLOR_BALANCE_H__
GtkWidget *
_pika_prop_gui_new_color_balance (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_COLOR_BALANCE_H__ */

View File

@ -0,0 +1,257 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-color-rotate.c
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "widgets/pikapropwidgets.h"
#include "pikapropgui.h"
#include "pikapropgui-color-rotate.h"
#include "pikapropgui-generic.h"
#include "pika-intl.h"
static void
invert_segment_clicked (GtkWidget *button,
GtkWidget *dial)
{
gdouble alpha, beta;
gboolean clockwise;
g_object_get (dial,
"alpha", &alpha,
"beta", &beta,
"clockwise-delta", &clockwise,
NULL);
g_object_set (dial,
"alpha", beta,
"beta", alpha,
"clockwise-delta", ! clockwise,
NULL);
}
static void
select_all_clicked (GtkWidget *button,
GtkWidget *dial)
{
gdouble alpha, beta;
gboolean clockwise;
g_object_get (dial,
"alpha", &alpha,
"clockwise-delta", &clockwise,
NULL);
beta = alpha - (clockwise ? -1 : 1) * 0.00001;
if (beta < 0)
beta += 2 * G_PI;
if (beta > 2 * G_PI)
beta -= 2 * G_PI;
g_object_set (dial,
"beta", beta,
NULL);
}
static GtkWidget *
pika_prop_angle_range_box_new (GObject *config,
const gchar *alpha_property_name,
const gchar *beta_property_name,
const gchar *clockwise_property_name)
{
GtkWidget *main_hbox;
GtkWidget *vbox;
GtkWidget *scale;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *invert_button;
GtkWidget *all_button;
GtkWidget *dial;
main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
scale = pika_prop_spin_scale_new (config, alpha_property_name,
1.0, 15.0, 2);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (scale), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_spin_scale_new (config, beta_property_name,
1.0, 15.0, 2);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (scale), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
button = pika_prop_check_button_new (config, clockwise_property_name,
_("Clockwise"));
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
invert_button = gtk_button_new_with_label (_("Invert Range"));
gtk_box_pack_start (GTK_BOX (hbox), invert_button, TRUE, TRUE, 0);
gtk_widget_show (invert_button);
all_button = gtk_button_new_with_label (_("Select All"));
gtk_box_pack_start (GTK_BOX (hbox), all_button, TRUE, TRUE, 0);
gtk_widget_show (all_button);
dial = pika_prop_angle_range_dial_new (config,
alpha_property_name,
beta_property_name,
clockwise_property_name);
gtk_box_pack_start (GTK_BOX (main_hbox), dial, FALSE, FALSE, 0);
g_signal_connect (invert_button, "clicked",
G_CALLBACK (invert_segment_clicked),
dial);
g_signal_connect (all_button, "clicked",
G_CALLBACK (select_all_clicked),
dial);
gtk_widget_show (main_hbox);
return main_hbox;
}
static GtkWidget *
pika_prop_polar_box_new (GObject *config,
const gchar *angle_property_name,
const gchar *radius_property_name)
{
GtkWidget *main_hbox;
GtkWidget *vbox;
GtkWidget *scale;
GtkWidget *polar;
main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_box_pack_start (GTK_BOX (main_hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
scale = pika_prop_spin_scale_new (config, angle_property_name,
1.0, 15.0, 2);
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (scale), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_spin_scale_new (config, radius_property_name,
1.0, 15.0, 2);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
polar = pika_prop_polar_new (config,
angle_property_name,
radius_property_name);
gtk_box_pack_start (GTK_BOX (main_hbox), polar, FALSE, FALSE, 0);
gtk_widget_show (main_hbox);
return main_hbox;
}
GtkWidget *
_pika_prop_gui_new_color_rotate (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *box;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
frame = pika_frame_new (_("Source Range"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
box = pika_prop_angle_range_box_new (config,
param_specs[1]->name,
param_specs[2]->name,
param_specs[0]->name);
gtk_container_add (GTK_CONTAINER (frame), box);
frame = pika_frame_new (_("Destination Range"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
box = pika_prop_angle_range_box_new (config,
param_specs[4]->name,
param_specs[5]->name,
param_specs[3]->name);
gtk_container_add (GTK_CONTAINER (frame), box);
frame = pika_frame_new (_("Gray Handling"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
box = _pika_prop_gui_new_generic (config,
param_specs + 6, 2,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
box = pika_prop_polar_box_new (config,
param_specs[8]->name,
param_specs[9]->name);
gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, FALSE, 0);
return main_vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-color-rotate.h
*
* 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 __PIKA_PROP_GUI_COLOR_ROTATE_H__
#define __PIKA_PROP_GUI_COLOR_ROTATE_H__
GtkWidget *
_pika_prop_gui_new_color_rotate (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_COLOR_ROTATE_H__ */

View File

@ -0,0 +1,141 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-color-to-alpha.c
* Copyright (C) 2017 Ell
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-color-to-alpha.h"
#include "pikapropgui-generic.h"
#include "pika-intl.h"
static void
threshold_picked (GObject *config,
gpointer identifier,
gdouble x,
gdouble y,
const Babl *sample_format,
const PikaRGB *picked_color)
{
PikaRGB *color;
gdouble threshold = 0.0;
g_object_get (config,
"color", &color,
NULL);
threshold = MAX (threshold, fabs (picked_color->r - color->r));
threshold = MAX (threshold, fabs (picked_color->g - color->g));
threshold = MAX (threshold, fabs (picked_color->b - color->b));
g_object_set (config,
identifier, threshold,
NULL);
g_free (color);
}
GtkWidget *
_pika_prop_gui_new_color_to_alpha (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
GtkWidget *button;
GtkWidget *hbox;
GtkWidget *scale;
const gchar *label;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
button = _pika_prop_gui_new_generic (config, param_specs, 1,
area, context, create_picker_func, NULL,
creator);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
scale = pika_prop_widget_new (config, "transparency-threshold",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
if (create_picker_func)
{
button = create_picker_func (creator,
"transparency-threshold",
PIKA_ICON_COLOR_PICKER_GRAY,
_("Pick farthest full-transparency color"),
/* pick_abyss = */ FALSE,
(PikaPickerCallback) threshold_picked,
config);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
}
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
scale = pika_prop_widget_new (config, "opacity-threshold",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
if (create_picker_func)
{
button = create_picker_func (creator,
"opacity-threshold",
PIKA_ICON_COLOR_PICKER_GRAY,
_("Pick nearest full-opacity color"),
/* pick_abyss = */ FALSE,
(PikaPickerCallback) threshold_picked,
config);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-color-to-alpha.h
*
* 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 __PIKA_PROP_GUI_COLOR_TO_ALPHA_H__
#define __PIKA_PROP_GUI_COLOR_TO_ALPHA_H__
GtkWidget *
_pika_prop_gui_new_color_to_alpha (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_COLOR_TO_ALPHA_H__ */

View File

@ -0,0 +1,305 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-convolution-matrix.c
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-convolution-matrix.h"
#include "pikapropgui-generic.h"
#include "pika-intl.h"
static const gchar *
convolution_matrix_prop_name (gint x,
gint y)
{
static const gchar * const prop_names[5][5] = {
{"a1", "b1", "c1", "d1", "e1"},
{"a2", "b2", "c2", "d2", "e2"},
{"a3", "b3", "c3", "d3", "e3"},
{"a4", "b4", "c4", "d4", "e4"},
{"a5", "b5", "c5", "d5", "e5"}};
return prop_names[y][x];
}
static void
convolution_matrix_rotate_flip (GtkWidget *button,
GObject *config)
{
gint rotate = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
"convolution-matrix-rotate"));
gint flip = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button),
"convolution-matrix-flip"));
gint x, y;
while (rotate--)
{
for (y = 0; y < 2; y++)
{
for (x = y; x < 4 - y; x++)
{
gint i;
gdouble temp;
g_object_get (config,
convolution_matrix_prop_name (x, y), &temp,
NULL);
for (i = 0; i < 4; i++)
{
gint next_x, next_y;
gdouble val;
next_x = 4 - y;
next_y = x;
if (i < 3)
{
g_object_get (config,
convolution_matrix_prop_name (next_x, next_y), &val,
NULL);
}
else
{
val = temp;
}
g_object_set (config,
convolution_matrix_prop_name (x, y), val,
NULL);
x = next_x;
y = next_y;
}
}
}
}
while (flip--)
{
for (y = 0; y < 5; y++)
{
for (x = 0; x < 2; x++)
{
gdouble val1, val2;
g_object_get (config,
convolution_matrix_prop_name (x, y), &val1,
NULL);
g_object_get (config,
convolution_matrix_prop_name (4 - x, y), &val2,
NULL);
g_object_set (config,
convolution_matrix_prop_name (x, y), val2,
NULL);
g_object_set (config,
convolution_matrix_prop_name (4 - x, y), val1,
NULL);
}
}
}
}
GtkWidget *
_pika_prop_gui_new_convolution_matrix (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkWidget *vbox;
GtkWidget *grid;
GtkWidget *hbox;
GtkWidget *scale;
GtkWidget *vbox2;
const gchar *label;
gint x, y;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
gtk_widget_show (vbox);
/* matrix */
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
gtk_widget_show (grid);
for (y = 0; y < 5; y++)
{
for (x = 0; x < 5; x++)
{
GtkWidget *spin;
spin = pika_prop_spin_button_new (config,
convolution_matrix_prop_name (x, y),
1.0, 10.0, 2);
gtk_entry_set_width_chars (GTK_ENTRY (spin), 8);
gtk_grid_attach (GTK_GRID (grid), spin, x, y, 1, 1);
}
}
/* rotate / flip buttons */
{
typedef struct
{
const gchar *tooltip;
const gchar *icon_name;
gint rotate;
gint flip;
} ButtonInfo;
gint i;
const ButtonInfo buttons[] = {
{
.tooltip = _("Rotate matrix 90° counter-clockwise"),
.icon_name = PIKA_ICON_OBJECT_ROTATE_270,
.rotate = 1,
.flip = 0
},
{
.tooltip = _("Rotate matrix 90° clockwise"),
.icon_name = PIKA_ICON_OBJECT_ROTATE_90,
.rotate = 3,
.flip = 0
},
{
.tooltip = _("Flip matrix horizontally"),
.icon_name = PIKA_ICON_OBJECT_FLIP_HORIZONTAL,
.rotate = 0,
.flip = 1
},
{
.tooltip = _("Flip matrix vertically"),
.icon_name = PIKA_ICON_OBJECT_FLIP_VERTICAL,
.rotate = 2,
.flip = 1
}};
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
for (i = 0; i < G_N_ELEMENTS (buttons); i++)
{
const ButtonInfo *info = &buttons[i];
GtkWidget *button;
GtkWidget *image;
button = gtk_button_new ();
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_set_tooltip_text (button, info->tooltip);
gtk_widget_set_can_focus (button, FALSE);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_widget_show (button);
image = gtk_image_new_from_icon_name (info->icon_name,
GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_object_set_data (G_OBJECT (button),
"convolution-matrix-rotate",
GINT_TO_POINTER (info->rotate));
g_object_set_data (G_OBJECT (button),
"convolution-matrix-flip",
GINT_TO_POINTER (info->flip));
g_signal_connect (button, "clicked",
G_CALLBACK (convolution_matrix_rotate_flip),
config);
}
}
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
gtk_widget_show (vbox);
/* divisor / offset spin scales */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
scale = pika_prop_widget_new (config, "divisor",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
scale = pika_prop_widget_new (config, "offset",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
/* rest of the properties */
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
vbox2 = _pika_prop_gui_new_generic (config,
param_specs + 27, 4,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
vbox2 = _pika_prop_gui_new_generic (config,
param_specs + 31,
n_param_specs - 31,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
return main_vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-convolution-matrix.h
*
* 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 __PIKA_PROP_GUI_CONVOLUTION_MATRIX_H__
#define __PIKA_PROP_GUI_CONVOLUTION_MATRIX_H__
GtkWidget *
_pika_prop_gui_new_convolution_matrix (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_CONVOLUTION_MATRIX_H__ */

View File

@ -0,0 +1,105 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-diffraction-patterns.c
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-diffraction-patterns.h"
#include "pikapropgui-generic.h"
#include "pika-intl.h"
GtkWidget *
_pika_prop_gui_new_diffraction_patterns (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *notebook;
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
notebook = gtk_notebook_new ();
vbox = _pika_prop_gui_new_generic (config,
param_specs + 0, 3,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox,
gtk_label_new (_("Frequencies")));
vbox = _pika_prop_gui_new_generic (config,
param_specs + 3, 3,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox,
gtk_label_new (_("Contours")));
vbox = _pika_prop_gui_new_generic (config,
param_specs + 6, 3,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox,
gtk_label_new (_("Sharp Edges")));
vbox = _pika_prop_gui_new_generic (config,
param_specs + 9, 3,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox,
gtk_label_new (_("Other Options")));
return notebook;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-diffraction-patterns.h
*
* 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 __PIKA_PROP_GUI_DIFFRACTION_PATTERNS_H__
#define __PIKA_PROP_GUI_DIFFRACTION_PATTERNS_H__
GtkWidget *
_pika_prop_gui_new_diffraction_patterns (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_DIFFRACTION_PATTERNS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui.h
* Copyright (C) 2017 Ell
*
* This program 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 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_PROP_GUI_EVAL_H__
#define __PIKA_PROP_GUI_EVAL_H__
gboolean pika_prop_eval_boolean (GObject *config,
GParamSpec *pspec,
const gchar *key,
gboolean default_value);
gchar * pika_prop_eval_string (GObject *config,
GParamSpec *pspec,
const gchar *key,
const gchar *default_value);
#endif /* __PIKA_PROP_GUI_EVAL_H__ */

View File

@ -0,0 +1,250 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-focus-blur.c
* Copyright (C) 2020 Ell
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-focus-blur.h"
#include "pika-intl.h"
static gint
find_param (GParamSpec **param_specs,
guint n_param_specs,
const gchar *name)
{
gint i;
for (i = 0; i < n_param_specs; i++)
{
if (! strcmp (param_specs[i]->name, name))
break;
}
return i;
}
static void
focus_callback (GObject *config,
GeglRectangle *area,
PikaLimitType type,
gdouble x,
gdouble y,
gdouble radius,
gdouble aspect_ratio,
gdouble angle,
gdouble inner_limit,
gdouble midpoint)
{
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
g_object_set (config,
"shape", type,
"x", x / area->width,
"y", y / area->height,
"radius", 2.0 * radius / area->width,
"focus", inner_limit,
"midpoint", midpoint,
"aspect-ratio", aspect_ratio,
"rotation", fmod (
fmod (angle * 180.0 / G_PI + 180.0, 360.0) +
360.0,
360.0) - 180.0,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerFocusCallback set_func;
GeglRectangle *area;
PikaLimitType shape;
gdouble radius;
gdouble focus;
gdouble midpoint;
gdouble x, y;
gdouble aspect_ratio;
gdouble rotation;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"shape", &shape,
"radius", &radius,
"focus", &focus,
"midpoint", &midpoint,
"x", &x,
"y", &y,
"aspect-ratio", &aspect_ratio,
"rotation", &rotation,
NULL);
set_func (set_data, area,
shape,
x * area->width,
y * area->height,
radius * area->width / 2.0,
aspect_ratio,
rotation / 180.0 * G_PI,
focus,
midpoint);
}
GtkWidget *
_pika_prop_gui_new_focus_blur (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
gint first_geometry_param;
gint last_geometry_param;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
first_geometry_param = find_param (param_specs, n_param_specs,
"shape") + 1;
last_geometry_param = find_param (param_specs, n_param_specs,
"high-quality");
if (last_geometry_param <= first_geometry_param)
{
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
}
else
{
GtkWidget *widget;
GtkWidget *expander;
GtkWidget *frame;
const gchar *label;
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
widget = pika_prop_widget_new (config,
"shape",
area, context,
create_picker_func,
create_controller_func,
creator,
&label);
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
widget = _pika_prop_gui_new_generic (config,
param_specs,
first_geometry_param - 1,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
widget = _pika_prop_gui_new_generic (config,
param_specs + last_geometry_param,
n_param_specs - last_geometry_param,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
expander = gtk_expander_new (_("Geometry Options"));
gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
gtk_widget_show (expander);
frame = pika_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (expander), frame);
gtk_widget_show (frame);
widget = _pika_prop_gui_new_generic (config,
param_specs + first_geometry_param,
last_geometry_param -
first_geometry_param,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_container_add (GTK_CONTAINER (frame), widget);
gtk_widget_show (widget);
}
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_FOCUS,
_("Focus Blur: "),
(GCallback) focus_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,40 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-focus-blur.h
* Copyright (C) 2020 Ell
*
* 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 __PIKA_PROP_GUI_FOCUS_BLUR_H__
#define __PIKA_PROP_GUI_FOCUS_BLUR_H__
GtkWidget *
_pika_prop_gui_new_focus_blur (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_FOCUS_BLUR_H__ */

View File

@ -0,0 +1,382 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-generic.c
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <string.h>
#include <stdlib.h>
#include <gegl.h>
#include <gegl-paramspecs.h>
#include <gtk/gtk.h>
#include "libpikacolor/pikacolor.h"
#include "libpikabase/pikabase.h"
#include "libpikaconfig/pikaconfig.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "gegl/pika-gegl-utils.h"
#include "core/pikacontext.h"
#include "widgets/pikapropwidgets.h"
#include "widgets/pikawidgets-utils.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pika-intl.h"
#define HAS_KEY(p,k,v) pika_gegl_param_spec_has_key (p, k, v)
static void pika_prop_gui_chain_toggled (PikaChainButton *chain,
GtkAdjustment *x_adj);
/* public functions */
GtkWidget *
_pika_prop_gui_new_generic (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkSizeGroup *label_group;
GList *chains = NULL;
gint i;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
label_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
for (i = 0; i < n_param_specs; i++)
{
GParamSpec *pspec = param_specs[i];
GParamSpec *next_pspec = NULL;
if (i < n_param_specs - 1)
next_pspec = param_specs[i + 1];
if (next_pspec &&
HAS_KEY (pspec, "axis", "x") &&
HAS_KEY (next_pspec, "axis", "y"))
{
GtkWidget *widget_x;
GtkWidget *widget_y;
const gchar *label_x;
const gchar *label_y;
GtkAdjustment *adj_x;
GtkAdjustment *adj_y;
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *chain;
i++;
widget_x = pika_prop_widget_new_from_pspec (config, pspec,
area, context,
create_picker_func,
create_controller_func,
creator,
&label_x);
widget_y = pika_prop_widget_new_from_pspec (config, next_pspec,
area, context,
create_picker_func,
create_controller_func,
creator,
&label_y);
adj_x = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget_x));
adj_y = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget_y));
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
pika_prop_gui_bind_container (widget_x, hbox);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
gtk_box_pack_start (GTK_BOX (vbox), widget_x, FALSE, FALSE, 0);
gtk_widget_show (widget_x);
gtk_box_pack_start (GTK_BOX (vbox), widget_y, FALSE, FALSE, 0);
gtk_widget_show (widget_y);
chain = pika_chain_button_new (PIKA_CHAIN_RIGHT);
gtk_box_pack_end (GTK_BOX (hbox), chain, FALSE, FALSE, 0);
gtk_widget_show (chain);
if (! HAS_KEY (pspec, "unit", "pixel-coordinate") &&
! HAS_KEY (pspec, "unit", "relative-coordinate") &&
gtk_adjustment_get_value (adj_x) ==
gtk_adjustment_get_value (adj_y))
{
GBinding *binding;
pika_chain_button_set_active (PIKA_CHAIN_BUTTON (chain), TRUE);
binding = g_object_bind_property (adj_x, "value",
adj_y, "value",
G_BINDING_BIDIRECTIONAL);
g_object_set_data (G_OBJECT (chain), "binding", binding);
}
g_object_set_data_full (G_OBJECT (chain), "x-property",
g_strdup (pspec->name), g_free);
g_object_set_data_full (G_OBJECT (chain), "y-property",
g_strdup (next_pspec->name), g_free);
chains = g_list_prepend (chains, chain);
g_signal_connect (chain, "toggled",
G_CALLBACK (pika_prop_gui_chain_toggled),
adj_x);
g_object_set_data (G_OBJECT (adj_x), "y-adjustment", adj_y);
if (create_picker_func &&
(HAS_KEY (pspec, "unit", "pixel-coordinate") ||
HAS_KEY (pspec, "unit", "relative-coordinate")))
{
GtkWidget *button;
gchar *pspec_name;
pspec_name = g_strconcat (pspec->name, ":",
next_pspec->name, NULL);
button = create_picker_func (creator,
pspec_name,
PIKA_ICON_CURSOR,
_("Pick coordinates from the image"),
/* pick_abyss = */ TRUE,
NULL, NULL);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_object_weak_ref (G_OBJECT (button),
(GWeakNotify) g_free, pspec_name);
}
}
else if (next_pspec &&
HAS_KEY (pspec, "role", "range-start") &&
HAS_KEY (next_pspec, "role", "range-end") &&
HAS_KEY (pspec, "unit", "luminance"))
{
GtkWidget *vbox;
GtkWidget *spin_scale;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *range;
const gchar *label_str;
const gchar *range_label_str;
gdouble step_increment;
gdouble page_increment;
gdouble ui_lower;
gdouble ui_upper;
i++;
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
spin_scale = pika_prop_widget_new_from_pspec (
config, pspec,
area, context,
create_picker_func,
create_controller_func,
creator,
&label_str);
gtk_widget_show (spin_scale);
g_object_set_data_full (G_OBJECT (vbox),
"pika-underlying-widget",
g_object_ref_sink (spin_scale),
g_object_unref);
range_label_str = gegl_param_spec_get_property_key (pspec,
"range-label");
if (range_label_str)
label_str = range_label_str;
gtk_spin_button_get_increments (GTK_SPIN_BUTTON (spin_scale),
&step_increment, &page_increment);
pika_spin_scale_get_scale_limits (PIKA_SPIN_SCALE (spin_scale),
&ui_lower, &ui_upper);
label = gtk_label_new_with_mnemonic (label_str);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
if (! range_label_str)
{
g_object_bind_property (spin_scale, "label",
label, "label",
G_BINDING_SYNC_CREATE);
}
frame = pika_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
range = pika_prop_range_new (config,
pspec->name, next_pspec->name,
step_increment, page_increment,
gtk_spin_button_get_digits (
GTK_SPIN_BUTTON (spin_scale)),
! HAS_KEY (pspec,
"range-sorted", "false"));
pika_prop_range_set_ui_limits (range, ui_lower, ui_upper);
gtk_container_add (GTK_CONTAINER (frame), range);
gtk_widget_show (range);
pika_prop_gui_bind_container (spin_scale, vbox);
pika_prop_gui_bind_tooltip (spin_scale, vbox);
}
else
{
GtkWidget *widget;
const gchar *label;
gboolean expand = FALSE;
widget = pika_prop_widget_new_from_pspec (config, pspec,
area, context,
create_picker_func,
create_controller_func,
creator,
&label);
if (GTK_IS_SCROLLED_WINDOW (widget))
expand = TRUE;
if (widget && label)
{
GtkWidget *l;
l = gtk_label_new_with_mnemonic (label);
gtk_label_set_xalign (GTK_LABEL (l), 0.0);
gtk_widget_show (l);
pika_prop_gui_bind_label (widget, l);
if (GTK_IS_SCROLLED_WINDOW (widget))
{
GtkWidget *frame;
/* don't set as frame title, it should not be bold */
gtk_box_pack_start (GTK_BOX (main_vbox), l, FALSE, FALSE, 0);
frame = pika_frame_new (NULL);
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
gtk_container_add (GTK_CONTAINER (frame), widget);
gtk_widget_show (widget);
pika_prop_gui_bind_container (widget, frame);
}
else
{
GtkWidget *hbox;
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox,
expand, expand, 0);
gtk_widget_show (hbox);
gtk_size_group_add_widget (label_group, l);
gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
pika_prop_gui_bind_container (widget, hbox);
}
}
else if (widget)
{
gtk_box_pack_start (GTK_BOX (main_vbox), widget,
expand, expand, 0);
gtk_widget_show (widget);
}
}
}
g_object_unref (label_group);
g_object_set_data_full (G_OBJECT (main_vbox), "chains", chains,
(GDestroyNotify) g_list_free);
gtk_widget_show (main_vbox);
return main_vbox;
}
/* private functions */
static void
pika_prop_gui_chain_toggled (PikaChainButton *chain,
GtkAdjustment *x_adj)
{
GBinding *binding;
GtkAdjustment *y_adj;
binding = g_object_get_data (G_OBJECT (chain), "binding");
y_adj = g_object_get_data (G_OBJECT (x_adj), "y-adjustment");
if (pika_chain_button_get_active (chain))
{
if (! binding)
binding = g_object_bind_property (x_adj, "value",
y_adj, "value",
G_BINDING_BIDIRECTIONAL);
}
else
{
g_clear_object (&binding);
}
g_object_set_data (G_OBJECT (chain), "binding", binding);
}

View File

@ -0,0 +1,40 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-generic.h
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 __PIKA_PROP_GUI_GENERIC_H__
#define __PIKA_PROP_GUI_GENERIC_H__
GtkWidget * _pika_prop_gui_new_generic (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_GENERIC_H__ */

View File

@ -0,0 +1,279 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-hue-saturation.c
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "operations/pikahuesaturationconfig.h"
#include "operations/pikaoperationhuesaturation.h"
#include "core/pikacontext.h"
#include "widgets/pikapropwidgets.h"
#include "pikapropgui.h"
#include "pikapropgui-hue-saturation.h"
#include "pika-intl.h"
#define COLOR_WIDTH 40
#define COLOR_HEIGHT 20
static void
hue_saturation_config_notify (GObject *object,
const GParamSpec *pspec,
GtkWidget *color_area)
{
PikaHueSaturationConfig *config = PIKA_HUE_SATURATION_CONFIG (object);
PikaHueRange range;
PikaRGB color;
static const PikaRGB default_colors[7] =
{
{ 0, 0, 0, },
{ 1.0, 0, 0, },
{ 1.0, 1.0, 0, },
{ 0, 1.0, 0, },
{ 0, 1.0, 1.0, },
{ 0, 0, 1.0, },
{ 1.0, 0, 1.0, }
};
range = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (color_area),
"hue-range"));
color = default_colors[range];
pika_operation_hue_saturation_map (config, &color, range, &color);
pika_color_area_set_color (PIKA_COLOR_AREA (color_area), &color);
}
static void
hue_saturation_range_callback (GtkWidget *widget,
GObject *config)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
PikaHueRange range;
pika_radio_button_update (widget, &range);
g_object_set (config,
"range", range,
NULL);
}
}
static void
hue_saturation_range_notify (GObject *object,
const GParamSpec *pspec,
GtkWidget *range_radio)
{
PikaHueSaturationConfig *config = PIKA_HUE_SATURATION_CONFIG (object);
pika_int_radio_group_set_active (GTK_RADIO_BUTTON (range_radio),
config->range);
}
GtkWidget *
_pika_prop_gui_new_hue_saturation (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *grid;
GtkWidget *scale;
GtkWidget *button;
GtkWidget *hbox;
GtkWidget *range_radio;
GSList *group = NULL;
gint i;
const struct
{
const gchar *label;
const gchar *tooltip;
gint label_col;
gint label_row;
gint frame_col;
gint frame_row;
}
hue_range_grid[] =
{
{ N_("M_aster"), N_("Adjust all colors"), 2, 3, 0, 0 },
{ N_("_R"), N_("Red"), 2, 1, 2, 0 },
{ N_("_Y"), N_("Yellow"), 1, 2, 0, 2 },
{ N_("_G"), N_("Green"), 1, 4, 0, 4 },
{ N_("_C"), N_("Cyan"), 2, 5, 2, 6 },
{ N_("_B"), N_("Blue"), 3, 4, 4, 4 },
{ N_("_M"), N_("Magenta"), 3, 2, 4, 2 }
};
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
frame = pika_frame_new (_("Select Primary Color to Adjust"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* The grid containing hue ranges */
grid = gtk_grid_new ();
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
gtk_grid_set_column_spacing (GTK_GRID (grid), 4);
gtk_grid_set_row_spacing (GTK_GRID (grid), 2);
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
/* the radio buttons for hue ranges */
for (i = 0; i < G_N_ELEMENTS (hue_range_grid); i++)
{
button = gtk_radio_button_new_with_mnemonic (group,
gettext (hue_range_grid[i].label));
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
g_object_set_data (G_OBJECT (button), "pika-item-data",
GINT_TO_POINTER (i));
pika_help_set_help_data (button,
gettext (hue_range_grid[i].tooltip),
NULL);
if (i == 0)
{
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
range_radio = button;
}
gtk_grid_attach (GTK_GRID (grid), button,
hue_range_grid[i].label_col,
hue_range_grid[i].label_row,
1, 1);
if (i > 0)
{
GtkWidget *color_area;
PikaRGB color = { 0, };
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_grid_attach (GTK_GRID (grid), frame,
hue_range_grid[i].frame_col,
hue_range_grid[i].frame_row,
1, 1);
gtk_widget_show (frame);
color_area = pika_color_area_new (&color, PIKA_COLOR_AREA_FLAT, 0);
gtk_widget_set_size_request (color_area, COLOR_WIDTH, COLOR_HEIGHT);
gtk_container_add (GTK_CONTAINER (frame), color_area);
gtk_widget_show (color_area);
g_object_set_data (G_OBJECT (color_area), "hue-range",
GINT_TO_POINTER (i));
g_signal_connect_object (config, "notify",
G_CALLBACK (hue_saturation_config_notify),
color_area, 0);
hue_saturation_config_notify (config, NULL, color_area);
}
g_signal_connect (button, "toggled",
G_CALLBACK (hue_saturation_range_callback),
config);
gtk_widget_show (button);
}
gtk_widget_show (grid);
/* Create the 'Overlap' option slider */
scale = pika_prop_spin_scale_new (config, "overlap", 0.01, 0.1, 0);
pika_prop_widget_set_factor (scale, 100.0, 1.0, 10.0, 1);
pika_spin_scale_set_label (PIKA_SPIN_SCALE (scale), _("_Overlap"));
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
frame = pika_frame_new (_("Adjust Selected Color"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
/* Create the hue scale widget */
scale = pika_prop_spin_scale_new (config, "hue",
1.0 / 180.0, 15.0 / 180.0, 0);
pika_prop_widget_set_factor (scale, 180.0, 1.0, 15.0, 1);
pika_spin_scale_set_label (PIKA_SPIN_SCALE (scale), _("_Hue"));
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
/* Create the lightness scale widget */
scale = pika_prop_spin_scale_new (config, "lightness", 0.01, 0.1, 0);
pika_prop_widget_set_factor (scale, 100.0, 1.0, 10.0, 1);
pika_spin_scale_set_label (PIKA_SPIN_SCALE (scale), _("_Lightness"));
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
/* Create the saturation scale widget */
scale = pika_prop_spin_scale_new (config, "saturation", 0.01, 0.1, 0);
pika_prop_widget_set_factor (scale, 100.0, 1.0, 10.0, 1);
pika_spin_scale_set_label (PIKA_SPIN_SCALE (scale), _("_Saturation"));
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
button = gtk_button_new_with_mnemonic (_("R_eset Color"));
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
g_signal_connect_swapped (button, "clicked",
G_CALLBACK (pika_hue_saturation_config_reset_range),
config);
g_signal_connect_object (config, "notify::range",
G_CALLBACK (hue_saturation_range_notify),
range_radio, 0);
hue_saturation_range_notify (config, NULL, range_radio);
return main_vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-hue-saturation.h
*
* 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 __PIKA_PROP_GUI_HUE_SATURATION_H__
#define __PIKA_PROP_GUI_HUE_SATURATION_H__
GtkWidget *
_pika_prop_gui_new_hue_saturation (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_HUE_SATURATION_H__ */

View File

@ -0,0 +1,155 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-motion-blur-circular.c
* Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-motion-blur-circular.h"
#include "pika-intl.h"
static void
line_callback (GObject *config,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2)
{
gdouble x, y;
gdouble angle;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
x = x1 / area->width;
y = y1 / area->height;
angle = atan2 (-(y2 - y1), x2 - x1);
angle = angle * 180.0 / G_PI;
if (angle < 0)
angle += 360.0;
g_object_set (config,
"center-x", x,
"center-y", y,
"angle", angle,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerLineCallback set_func;
GeglRectangle *area;
gdouble x, y;
gdouble angle;
gdouble x1, y1, x2, y2;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"center-x", &x,
"center-y", &y,
"angle", &angle,
NULL);
angle = angle / 180.0 * G_PI;
x1 = x * area->width;
y1 = y * area->height;
x2 = x1 + cos (angle) * 100;
y2 = y1 - sin (angle) * 100;
set_func (set_data, area, x1, y1, x2, y2);
}
GtkWidget *
_pika_prop_gui_new_motion_blur_circular (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_LINE,
_("Circular Motion Blur: "),
(GCallback) line_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-motion-blur-circular.h
*
* 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 __PIKA_PROP_GUI_MOTION_BLUR_CIRCULAR_H__
#define __PIKA_PROP_GUI_MOTION_BLUR_CIRCULAR_H__
GtkWidget *
_pika_prop_gui_new_motion_blur_circular (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_MOTION_BLUR_CIRCULAR_H__ */

View File

@ -0,0 +1,149 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-motion-blur-linear.c
* Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-motion-blur-linear.h"
#include "pika-intl.h"
static void
line_callback (GObject *config,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2)
{
gdouble length;
gdouble angle;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
length = sqrt (SQR (x2 - x1) + SQR (y2 - y1));
angle = atan2 (y2 - y1, x2 - x1);
angle = angle / G_PI * 180.0;
g_object_set (config,
"length", length,
"angle", angle,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerLineCallback set_func;
GeglRectangle *area;
gdouble length;
gdouble angle;
gdouble x1, y1, x2, y2;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"length", &length,
"angle", &angle,
NULL);
angle = angle / 180.0 * G_PI;
x1 = area->x + area->width / 2.0;
y1 = area->x + area->height / 2.0;
x2 = x1 + cos (angle) * length;
y2 = y1 + sin (angle) * length;
set_func (set_data, area, x1, y1, x2, y2);
}
GtkWidget *
_pika_prop_gui_new_motion_blur_linear (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_LINE,
_("Linear Motion Blur: "),
(GCallback) line_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-motion-blur-linear.h
*
* 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 __PIKA_PROP_GUI_MOTION_BLUR_LINEAR_H__
#define __PIKA_PROP_GUI_MOTION_BLUR_LINEAR_H__
GtkWidget *
_pika_prop_gui_new_motion_blur_linear (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_MOTION_BLUR_LINEAR_H__ */

View File

@ -0,0 +1,150 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-motion-blur-zoom.c
* Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-motion-blur-zoom.h"
#include "pika-intl.h"
static void
line_callback (GObject *config,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2)
{
gdouble x, y;
gdouble radius;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
x = x1 / area->width;
y = y1 / area->height;
radius = x2 - x1;
radius = CLAMP (radius / 100.0, -0.5, 1.0);
g_object_set (config,
"center-x", x,
"center-y", y,
"factor", radius,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerLineCallback set_func;
GeglRectangle *area;
gdouble x, y;
gdouble radius;
gdouble x1, y1, x2, y2;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"center-x", &x,
"center-y", &y,
"factor", &radius,
NULL);
x1 = x * area->width;
y1 = y * area->height;
x2 = x1 + radius * 100.0;
y2 = y1;
set_func (set_data, area, x1, y1, x2, y2);
}
GtkWidget *
_pika_prop_gui_new_motion_blur_zoom (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_LINE,
_("Zoom Motion Blur: "),
(GCallback) line_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-motion-blur-zoom.h
*
* 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 __PIKA_PROP_GUI_MOTION_BLUR_ZOOM_H__
#define __PIKA_PROP_GUI_MOTION_BLUR_ZOOM_H__
GtkWidget *
_pika_prop_gui_new_motion_blur_zoom (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_MOTION_BLUR_ZOOM_H__ */

View File

@ -0,0 +1,448 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-newsprint.c
* Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-newsprint.h"
#include "pika-intl.h"
typedef enum
{
COLOR_MODEL_WHITE_ON_BLACK,
COLOR_MODEL_BLACK_ON_WHITE,
COLOR_MODEL_RGB,
COLOR_MODEL_CMYK,
N_COLOR_MODELS
} ColorModel;
typedef enum
{
PATTERN_LINE,
PATTERN_CIRCLE,
PATTERN_DIAMOND,
PATTERN_PSCIRCLE,
PATTERN_CROSS,
N_PATTERNS
} Pattern;
typedef struct _Newsprint Newsprint;
struct _Newsprint
{
GObject *config;
GtkWidget *notebook;
GtkWidget *pattern_check;
GtkWidget *period_check;
GtkWidget *angle_check;
};
/* local function prototypes */
static void newsprint_color_model_notify (GObject *config,
const GParamSpec *pspec,
GtkWidget *label);
static void newsprint_model_prop_notify (GObject *config,
const GParamSpec *pspec,
Newsprint *np);
static void newsprint_lock_patterns_toggled (GtkWidget *widget,
Newsprint *np);
static void newsprint_lock_periods_toggled (GtkWidget *widget,
Newsprint *np);
static void newsprint_lock_angles_toggled (GtkWidget *widget,
Newsprint *np);
static const gchar *label_strings[N_COLOR_MODELS][4] =
{
{ NULL, NULL, NULL, N_("White") },
{ NULL, NULL, NULL, N_("Black") },
{ N_("Red"), N_("Green"), N_("Blue"), NULL },
{ N_("Cyan"), N_("Magenta"), N_("Yellow"), N_("Black") }
};
static const gchar *pattern_props[] =
{
"pattern2",
"pattern3",
"pattern4",
"pattern"
};
static const gchar *period_props[] =
{
"period2",
"period3",
"period4",
"period"
};
static const gchar *angle_props[] =
{
"angle2",
"angle3",
"angle4",
"angle"
};
/* public functions */
GtkWidget *
_pika_prop_gui_new_newsprint (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
Newsprint *np;
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *combo;
GtkWidget *labels[4];
GtkWidget *pages[4];
GtkWidget *check;
gint i;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
np = g_new0 (Newsprint, 1);
np->config = config;
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
g_object_set_data_full (G_OBJECT (main_vbox), "newsprint", np,
(GDestroyNotify) g_free);
frame = pika_frame_new (_("Channels"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
combo = _pika_prop_gui_new_generic (config,
param_specs + 0, 1,
area,
context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
gtk_widget_show (combo);
np->notebook = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (vbox), np->notebook, FALSE, FALSE, 0);
gtk_widget_show (np->notebook);
for (i = 0; i < 4; i++)
{
GtkWidget *widget;
const gchar *unused;
gint remaining;
labels[i] = gtk_label_new (NULL);
pages[i] = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
g_object_set_data (G_OBJECT (labels[i]), "channel", GINT_TO_POINTER (i));
g_signal_connect_object (config, "notify::color-model",
G_CALLBACK (newsprint_color_model_notify),
G_OBJECT (labels[i]), 0);
newsprint_color_model_notify (config, NULL, labels[i]);
gtk_container_set_border_width (GTK_CONTAINER (pages[i]), 6);
gtk_notebook_append_page (GTK_NOTEBOOK (np->notebook),
pages[i], labels[i]);
widget = pika_prop_widget_new_from_pspec (config,
param_specs[1 + 3 * i],
area, context,
create_picker_func,
create_controller_func,
creator, &unused);
gtk_box_pack_start (GTK_BOX (pages[i]), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
g_object_bind_property (G_OBJECT (widget), "visible",
G_OBJECT (pages[i]), "visible",
G_BINDING_SYNC_CREATE);
if (i == 3)
remaining = 3;
else
remaining = 2;
widget = _pika_prop_gui_new_generic (config,
param_specs + 2 + 3 * i, remaining,
area, context,
create_picker_func,
create_controller_func,
creator);
gtk_box_pack_start (GTK_BOX (pages[i]), widget, FALSE, FALSE, 0);
gtk_widget_show (widget);
}
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
np->pattern_check = check =
gtk_check_button_new_with_mnemonic (_("_Lock patterns"));
gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
gtk_widget_show (check);
g_signal_connect (check, "toggled",
G_CALLBACK (newsprint_lock_patterns_toggled),
np);
np->period_check = check =
gtk_check_button_new_with_mnemonic (_("Loc_k periods"));
gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
gtk_widget_show (check);
g_signal_connect (check, "toggled",
G_CALLBACK (newsprint_lock_periods_toggled),
np);
np->angle_check = check =
gtk_check_button_new_with_mnemonic (_("Lock a_ngles"));
gtk_box_pack_start (GTK_BOX (hbox), check, FALSE, FALSE, 0);
gtk_widget_show (check);
g_signal_connect (check, "toggled",
G_CALLBACK (newsprint_lock_angles_toggled),
np);
frame = pika_frame_new (_("Quality"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = _pika_prop_gui_new_generic (config,
param_specs + 14, 1,
area,
context,
create_picker_func,
create_controller_func,
creator);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
frame = pika_frame_new (_("Effects"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = _pika_prop_gui_new_generic (config,
param_specs + 15, 3,
area,
context,
create_picker_func,
create_controller_func,
creator);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
g_signal_connect (config, "notify",
G_CALLBACK (newsprint_model_prop_notify),
np);
return main_vbox;
}
/* private functions */
static void
newsprint_color_model_notify (GObject *config,
const GParamSpec *pspec,
GtkWidget *label)
{
ColorModel model;
gint channel;
g_object_get (config,
"color-model", &model,
NULL);
channel =
GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label), "channel"));
if (label_strings[model][channel])
gtk_label_set_text (GTK_LABEL (label),
gettext (label_strings[model][channel]));
}
static gboolean
newsprint_sync_model_props (Newsprint *np,
const GParamSpec *pspec,
const gchar **props,
gint n_props)
{
gint i;
for (i = 0; i < n_props; i++)
{
if (! strcmp (pspec->name, props[i]))
{
GValue value = G_VALUE_INIT;
gint j;
g_value_init (&value, pspec->value_type);
g_object_get_property (np->config, pspec->name, &value);
for (j = 0; j < n_props; j++)
{
if (i != j)
{
g_signal_handlers_block_by_func (np->config,
newsprint_model_prop_notify,
np);
g_object_set_property (np->config, props[j], &value);
g_signal_handlers_unblock_by_func (np->config,
newsprint_model_prop_notify,
np);
}
}
g_value_unset (&value);
return TRUE;
}
}
return FALSE;
}
static void
newsprint_model_prop_notify (GObject *config,
const GParamSpec *pspec,
Newsprint *np)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (np->pattern_check)) &&
newsprint_sync_model_props (np, pspec,
pattern_props, G_N_ELEMENTS (pattern_props)))
return;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (np->period_check)) &&
newsprint_sync_model_props (np, pspec,
period_props, G_N_ELEMENTS (period_props)))
return;
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (np->angle_check)) &&
newsprint_sync_model_props (np, pspec,
angle_props, G_N_ELEMENTS (angle_props)))
return;
}
static void
newsprint_lock_patterns_toggled (GtkWidget *widget,
Newsprint *np)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
GParamSpec *pspec;
gint channel;
channel = gtk_notebook_get_current_page (GTK_NOTEBOOK (np->notebook));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (np->config),
pattern_props[channel]);
newsprint_sync_model_props (np, pspec,
pattern_props, G_N_ELEMENTS (pattern_props));
}
}
static void
newsprint_lock_periods_toggled (GtkWidget *widget,
Newsprint *np)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
GParamSpec *pspec;
gint channel;
channel = gtk_notebook_get_current_page (GTK_NOTEBOOK (np->notebook));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (np->config),
period_props[channel]);
newsprint_sync_model_props (np, pspec,
period_props, G_N_ELEMENTS (period_props));
}
}
static void
newsprint_lock_angles_toggled (GtkWidget *widget,
Newsprint *np)
{
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
{
GParamSpec *pspec;
gint channel;
channel = gtk_notebook_get_current_page (GTK_NOTEBOOK (np->notebook));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (np->config),
angle_props[channel]);
newsprint_sync_model_props (np, pspec,
angle_props, G_N_ELEMENTS (angle_props));
}
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-newsprint.h
*
* 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 __PIKA_PROP_GUI_NEWSPRINT_H__
#define __PIKA_PROP_GUI_NEWSPRINT_H__
GtkWidget *
_pika_prop_gui_new_newsprint (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_NEWSPRINT_H__ */

View File

@ -0,0 +1,148 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-panorama-projection.c
* Copyright (C) 2018 Ell
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-panorama-projection.h"
#include "pika-intl.h"
static void
gyroscope_callback (GObject *config,
GeglRectangle *area,
gdouble yaw,
gdouble pitch,
gdouble roll,
gdouble zoom,
gboolean invert)
{
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
g_object_set (config,
"pan", -yaw,
"tilt", -pitch,
"spin", -roll,
"zoom", CLAMP (100.0 * zoom, 0.01, 1000.0),
"inverse", invert,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerGyroscopeCallback set_func;
GeglRectangle *area;
gdouble pan;
gdouble tilt;
gdouble spin;
gdouble zoom;
gboolean inverse;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"pan", &pan,
"tilt", &tilt,
"spin", &spin,
"zoom", &zoom,
"inverse", &inverse,
NULL);
set_func (set_data,
area,
-pan, -tilt, -spin,
zoom / 100.0,
inverse);
}
GtkWidget *
_pika_prop_gui_new_panorama_projection (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_GYROSCOPE,
_("Panorama Projection: "),
(GCallback) gyroscope_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-panorama-projection.h
*
* 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 __PIKA_PROP_GUI_PANORAMA_PROJECTION_H__
#define __PIKA_PROP_GUI_PANORAMA_PROJECTION_H__
GtkWidget *
_pika_prop_gui_new_panorama_projection (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_PANORAMA_PROJECTION_H__ */

View File

@ -0,0 +1,338 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-recursive-transform.c
* Copyright (C) 2018 Ell
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-recursive-transform.h"
#include "pika-intl.h"
#define MAX_N_TRANSFORMS 10
static void
add_transform (GtkButton *button,
GObject *config)
{
gchar *transform;
gchar *new_transform;
g_object_get (config,
"transform", &transform,
NULL);
new_transform = g_strdup_printf ("%s;matrix (1, 0, 0, 0, 1, 0, 0, 0, 1)",
transform);
g_object_set (config,
"transform", new_transform,
NULL);
g_free (transform);
g_free (new_transform);
}
static void
duplicate_transform (GtkButton *button,
GObject *config)
{
gchar *transform;
gchar *new_transform;
gchar *delim;
g_object_get (config,
"transform", &transform,
NULL);
delim = strrchr (transform, ';');
if (! delim)
delim = transform;
else
delim++;
new_transform = g_strdup_printf ("%s;%s", transform, delim);
g_object_set (config,
"transform", new_transform,
NULL);
g_free (transform);
g_free (new_transform);
}
static void
remove_transform (GtkButton *button,
GObject *config)
{
gchar *transform;
gchar *delim;
g_object_get (config,
"transform", &transform,
NULL);
delim = strrchr (transform, ';');
if (delim)
{
*delim = '\0';
g_object_set (config,
"transform", transform,
NULL);
}
g_free (transform);
}
static void
transform_grids_callback (GObject *config,
GeglRectangle *area,
const PikaMatrix3 *transforms,
gint n_transforms)
{
GString *transforms_str = g_string_new (NULL);
gchar *transform_str;
gint i;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
for (i = 0; i < n_transforms; i++)
{
if (i > 0)
g_string_append (transforms_str, ";");
transform_str = gegl_matrix3_to_string ((GeglMatrix3 *) &transforms[i]);
g_string_append (transforms_str, transform_str);
g_free (transform_str);
}
transform_str = g_string_free (transforms_str, FALSE);
g_object_set (config,
"transform", transform_str,
NULL);
g_free (transform_str);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
GtkWidget *add_button;
GtkWidget *duplicate_button;
GtkWidget *remove_button;
PikaControllerTransformGridsCallback set_func;
GeglRectangle *area;
gchar *transform_str;
gchar **transform_strs;
PikaMatrix3 *transforms;
gint n_transforms;
gint i;
add_button = g_object_get_data (G_OBJECT (config), "add-transform-button");
duplicate_button = g_object_get_data (G_OBJECT (config), "duplicate-transform-button");
remove_button = g_object_get_data (G_OBJECT (config), "remove-transform-button");
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"transform", &transform_str,
NULL);
transform_strs = g_strsplit (transform_str, ";", -1);
g_free (transform_str);
for (n_transforms = 0; transform_strs[n_transforms]; n_transforms++);
transforms = g_new (PikaMatrix3, n_transforms);
for (i = 0; i < n_transforms; i++)
{
gegl_matrix3_parse_string ((GeglMatrix3 *) &transforms[i],
transform_strs[i]);
}
set_func (set_data, area, transforms, n_transforms);
g_strfreev (transform_strs);
g_free (transforms);
gtk_widget_set_sensitive (add_button, n_transforms < MAX_N_TRANSFORMS);
gtk_widget_set_sensitive (duplicate_button, n_transforms < MAX_N_TRANSFORMS);
gtk_widget_set_sensitive (remove_button, n_transforms > 1);
}
GtkWidget *
_pika_prop_gui_new_recursive_transform (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
/* skip the "transform" property, which is controlled by a transform-grid
* controller.
*/
if (create_controller_func)
{
param_specs++;
n_param_specs--;
}
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GtkWidget *outer_vbox;
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *image;
GCallback set_func;
gpointer set_data;
outer_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL,
gtk_box_get_spacing (GTK_BOX (vbox)));
gtk_box_pack_start (GTK_BOX (outer_vbox), vbox, FALSE, FALSE, 0);
gtk_widget_show (vbox);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
gtk_box_pack_start (GTK_BOX (outer_vbox), hbox, FALSE, FALSE, 2);
gtk_widget_show (hbox);
button = gtk_button_new ();
pika_help_set_help_data (button,
_("Add transform"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
image = gtk_image_new_from_icon_name (PIKA_ICON_LIST_ADD,
GTK_ICON_SIZE_MENU);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect (button, "clicked",
G_CALLBACK (add_transform),
config);
g_object_set_data (config, "add-transform-button", button);
button = gtk_button_new ();
pika_help_set_help_data (button,
_("Duplicate transform"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
image = gtk_image_new_from_icon_name (PIKA_ICON_OBJECT_DUPLICATE,
GTK_ICON_SIZE_MENU);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect (button, "clicked",
G_CALLBACK (duplicate_transform),
config);
g_object_set_data (config, "duplicate-transform-button", button);
button = gtk_button_new ();
pika_help_set_help_data (button,
_("Remove transform"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
image = gtk_image_new_from_icon_name (PIKA_ICON_LIST_REMOVE,
GTK_ICON_SIZE_MENU);
gtk_container_add (GTK_CONTAINER (button), image);
gtk_widget_show (image);
g_signal_connect (button, "clicked",
G_CALLBACK (remove_transform),
config);
g_object_set_data (config, "remove-transform-button", button);
vbox = outer_vbox;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_TRANSFORM_GRIDS,
_("Recursive Transform: "),
(GCallback) transform_grids_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-recursive-transform.h
*
* 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 __PIKA_PROP_GUI_RECURSIVE_TRANSFORM_H__
#define __PIKA_PROP_GUI_RECURSIVE_TRANSFORM_H__
GtkWidget *
_pika_prop_gui_new_recursive_transform (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_RECURSIVE_TRANSFORM_H__ */

View File

@ -0,0 +1,119 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-shadows-highlights.c
* Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-shadows-highlights.h"
#include "pika-intl.h"
GtkWidget *
_pika_prop_gui_new_shadows_highlights (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *scale;
const gchar *label;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
frame = pika_frame_new (_("Shadows"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
scale = pika_prop_widget_new (config, "shadows",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "shadows-ccorrect",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
frame = pika_frame_new (_("Highlights"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
scale = pika_prop_widget_new (config, "highlights",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "highlights-ccorrect",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
frame = pika_frame_new (_("Common"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
scale = pika_prop_widget_new (config, "whitepoint",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "radius",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
scale = pika_prop_widget_new (config, "compress",
area, context, NULL, NULL, NULL, &label);
gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0);
return main_vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-shadows-highlights.h
*
* 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 __PIKA_PROP_GUI_SHADOWS_HIGHLIGHTS_H__
#define __PIKA_PROP_GUI_SHADOWS_HIGHLIGHTS_H__
GtkWidget *
_pika_prop_gui_new_shadows_highlights (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_SHADOWS_HIGHLIGHTS_H__ */

View File

@ -0,0 +1,243 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-spiral.c
* Copyright (C) 2017 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-spiral.h"
#include "pika-intl.h"
typedef enum
{
GEGL_SPIRAL_TYPE_LINEAR,
GEGL_SPIRAL_TYPE_LOGARITHMIC
} GeglSpiralType;
static void
slider_line_callback (GObject *config,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
const PikaControllerSlider *sliders,
gint n_sliders)
{
GeglSpiralType type;
gdouble x, y;
gdouble radius;
gdouble rotation;
gdouble base;
gdouble balance;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
g_object_get (config,
"type", &type,
"base", &base,
"balance", &balance,
NULL);
x = x1 / area->width;
y = y1 / area->height;
radius = sqrt (SQR (x2 - x1) + SQR (y2 - y1));
rotation = atan2 (-(y2 - y1), x2 - x1) * 180 / G_PI;
if (rotation < 0)
rotation += 360.0;
switch (type)
{
case GEGL_SPIRAL_TYPE_LINEAR:
balance = 3.0 - 4.0 * sliders[0].value;
break;
case GEGL_SPIRAL_TYPE_LOGARITHMIC:
{
gdouble old_base = base;
base = 1.0 / sliders[1].value;
base = MIN (base, 1000000.0);
/* keep "balance" fixed when changing "base", or when "base" is 1, in
* which case there's no inverse mapping for the slider value, and we
* can get NaN.
*/
if (base == old_base && base > 1.0)
{
balance = -4.0 * log (sliders[0].value) / log (base) - 1.0;
balance = CLAMP (balance, -1.0, 1.0);
}
}
break;
}
g_object_set (config,
"x", x,
"y", y,
"radius", radius,
"base", base,
"rotation", rotation,
"balance", balance,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerSliderLineCallback set_func;
GeglRectangle *area;
GeglSpiralType type;
gdouble x, y;
gdouble radius;
gdouble rotation;
gdouble base;
gdouble balance;
gdouble x1, y1, x2, y2;
PikaControllerSlider sliders[2];
gint n_sliders = 0;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"type", &type,
"x", &x,
"y", &y,
"radius", &radius,
"rotation", &rotation,
"base", &base,
"balance", &balance,
NULL);
x1 = x * area->width;
y1 = y * area->height;
x2 = x1 + cos (rotation * (G_PI / 180.0)) * radius;
y2 = y1 - sin (rotation * (G_PI / 180.0)) * radius;
switch (type)
{
case GEGL_SPIRAL_TYPE_LINEAR:
n_sliders = 1;
/* balance */
sliders[0] = PIKA_CONTROLLER_SLIDER_DEFAULT;
sliders[0].min = 0.5;
sliders[0].max = 1.0;
sliders[0].value = 0.5 + (1.0 - balance) / 4.0;
break;
case GEGL_SPIRAL_TYPE_LOGARITHMIC:
n_sliders = 2;
/* balance */
sliders[0] = PIKA_CONTROLLER_SLIDER_DEFAULT;
sliders[0].min = 1.0 / sqrt (base);
sliders[0].max = 1.0;
sliders[0].value = pow (base, -(balance + 1.0) / 4.0);
/* base */
sliders[1] = PIKA_CONTROLLER_SLIDER_DEFAULT;
sliders[1].min = 0.0;
sliders[1].max = 1.0;
sliders[1].value = 1.0 / base;
break;
}
set_func (set_data, area, x1, y1, x2, y2, sliders, n_sliders);
}
GtkWidget *
_pika_prop_gui_new_spiral (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_SLIDER_LINE,
_("Spiral: "),
(GCallback) slider_line_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-spiral.h
*
* 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 __PIKA_PROP_GUI_SPIRAL_H__
#define __PIKA_PROP_GUI_SPIRAL_H__
GtkWidget *
_pika_prop_gui_new_spiral (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_SPIRAL_H__ */

View File

@ -0,0 +1,148 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-supernova.c
* Copyright (C) 2017 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-supernova.h"
#include "pika-intl.h"
static void
line_callback (GObject *config,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2)
{
gdouble x, y;
gint radius;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
x = x1 / area->width;
y = y1 / area->height;
radius = sqrt (SQR (x2 - x1) + SQR (y2 - y1));
g_object_set (config,
"center-x", x,
"center-y", y,
"radius", radius,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerLineCallback set_func;
GeglRectangle *area;
gdouble x, y;
gint radius;
gdouble x1, y1, x2, y2;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"center-x", &x,
"center-y", &y,
"radius", &radius,
NULL);
x1 = x * area->width;
y1 = y * area->height;
x2 = x1 + radius;
y2 = y1;
set_func (set_data, area, x1, y1, x2, y2);
}
GtkWidget *
_pika_prop_gui_new_supernova (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_LINE,
_("Supernova: "),
(GCallback) line_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,39 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-supernova.h
*
* 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 __PIKA_PROP_GUI_SUPERNOVA_H__
#define __PIKA_PROP_GUI_SUPERNOVA_H__
GtkWidget *
_pika_prop_gui_new_supernova (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_SUPERNOVA_H__ */

View File

@ -0,0 +1,208 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-utils.c
* Copyright (C) 2002-2017 Michael Natterer <mitch@gimp.org>
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "pikapropgui-utils.h"
#include "pika-intl.h"
/* local function prototypes */
static gboolean pika_prop_kelvin_presets_button_press (GtkWidget *widget,
GdkEventButton *bevent,
GtkMenu *menu);
static void pika_prop_kelvin_presets_activate (GtkWidget *widget,
GObject *config);
static void pika_prop_random_seed_new_clicked (GtkButton *button,
GtkAdjustment *adj);
/* public functions */
GtkWidget *
pika_prop_kelvin_presets_new (GObject *config,
const gchar *property_name)
{
GtkWidget *button;
GtkWidget *menu;
gint i;
const struct
{
gdouble kelvin;
const gchar *label;
}
kelvin_presets[] =
{
{ 1700, N_("1,700 K Match flame") },
{ 1850, N_("1,850 K Candle flame, sunset/sunrise") },
{ 2700, N_("2,700 K - Soft (or warm) LED lamps") },
{ 3000, N_("3,000 K Soft (or warm) white compact fluorescent lamps") },
{ 3200, N_("3,200 K Studio lamps, photofloods, etc.") },
{ 3300, N_("3,300 K Incandescent lamps") },
{ 3350, N_("3,350 K Studio \"CP\" light") },
{ 4000, N_("4,000 K - Cold (daylight) LED lamps") },
{ 4100, N_("4,100 K Moonlight") },
{ 5000, N_("5,000 K D50") },
{ 5000, N_("5,000 K Cool white/daylight compact fluorescent lamps") },
{ 5000, N_("5,000 K Horizon daylight") },
{ 5500, N_("5,500 K D55") },
{ 5500, N_("5,500 K Vertical daylight, electronic flash") },
{ 6200, N_("6,200 K Xenon short-arc lamp") },
{ 6500, N_("6,500 K D65") },
{ 6500, N_("6,500 K Daylight, overcast") },
{ 7500, N_("7,500 K D75") },
{ 9300, N_("9,300 K") }
};
button = gtk_button_new ();
gtk_widget_set_can_focus (button, FALSE);
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
gtk_button_set_image (GTK_BUTTON (button),
gtk_image_new_from_icon_name (PIKA_ICON_MENU_LEFT,
GTK_ICON_SIZE_MENU));
menu = gtk_menu_new ();
gtk_menu_attach_to_widget (GTK_MENU (menu), button, NULL);
pika_help_set_help_data (button,
_("Choose from a list of common "
"color temperatures"), NULL);
g_signal_connect (button, "button-press-event",
G_CALLBACK (pika_prop_kelvin_presets_button_press),
menu);
for (i = 0; i < G_N_ELEMENTS (kelvin_presets); i++)
{
GtkWidget *item;
gdouble *kelvin;
item = gtk_menu_item_new_with_label (gettext (kelvin_presets[i].label));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item);
g_object_set_data_full (G_OBJECT (item), "property-name",
g_strdup (property_name),
(GDestroyNotify) g_free);
kelvin = g_new (gdouble, 1);
*kelvin = kelvin_presets[i].kelvin;
g_object_set_data_full (G_OBJECT (item), "kelvin",
kelvin, (GDestroyNotify) g_free);
g_signal_connect (item, "activate",
G_CALLBACK (pika_prop_kelvin_presets_activate),
config);
}
return button;
}
GtkWidget *
pika_prop_random_seed_new (GObject *config,
const gchar *property_name)
{
GtkAdjustment *adj;
GtkWidget *hbox;
GtkWidget *spin;
GtkWidget *button;
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
spin = pika_prop_spin_button_new (config, property_name,
1.0, 10.0, 0);
gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0);
gtk_widget_show (spin);
button = gtk_button_new_with_label (_("New Seed"));
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin));
g_signal_connect (button, "clicked",
G_CALLBACK (pika_prop_random_seed_new_clicked),
adj);
return hbox;
}
/* private functions */
static gboolean
pika_prop_kelvin_presets_button_press (GtkWidget *widget,
GdkEventButton *bevent,
GtkMenu *menu)
{
if (bevent->type == GDK_BUTTON_PRESS)
{
gtk_menu_popup_at_widget (menu, widget,
GDK_GRAVITY_WEST,
GDK_GRAVITY_NORTH_EAST,
(GdkEvent *) bevent);
}
return TRUE;
}
static void
pika_prop_kelvin_presets_activate (GtkWidget *widget,
GObject *config)
{
const gchar *property_name;
gdouble *kelvin;
property_name = g_object_get_data (G_OBJECT (widget), "property-name");
kelvin = g_object_get_data (G_OBJECT (widget), "kelvin");
if (property_name && kelvin)
g_object_set (config, property_name, *kelvin, NULL);
}
static void
pika_prop_random_seed_new_clicked (GtkButton *button,
GtkAdjustment *adj)
{
guint32 value;
value = floor (g_random_double_range (gtk_adjustment_get_lower (adj),
gtk_adjustment_get_upper (adj) + 1.0));
gtk_adjustment_set_value (adj, value);
}

View File

@ -0,0 +1,36 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-utils.h
* Copyright (C) 2002-2017 Michael Natterer <mitch@gimp.org>
*
* 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 __PIKA_PROP_GUI_UTILS_H__
#define __PIKA_PROP_GUI_UTILS_H__
GtkWidget * pika_prop_kelvin_presets_new (GObject *config,
const gchar *property_name);
GtkWidget * pika_prop_random_seed_new (GObject *config,
const gchar *property_name);
#endif /* __PIKA_PROP_GUI_UTILS_H__ */

View File

@ -0,0 +1,206 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-vignette.c
* Copyright (C) 2020 Ell
*
* 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 <gegl.h>
#include <gtk/gtk.h>
#include "libpikamath/pikamath.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "core/pikacontext.h"
#include "pikapropgui.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-vignette.h"
#include "pika-intl.h"
#define MAX_GAMMA 1000.0
static void
focus_callback (GObject *config,
GeglRectangle *area,
PikaLimitType type,
gdouble x,
gdouble y,
gdouble radius,
gdouble aspect_ratio,
gdouble angle,
gdouble inner_limit,
gdouble midpoint)
{
gdouble proportion;
gdouble squeeze;
gdouble scale;
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
g_object_get (config,
"proportion", &proportion,
NULL);
if (aspect_ratio >= 0.0)
scale = 1.0 - aspect_ratio;
else
scale = 1.0 / (1.0 + aspect_ratio);
scale /= 1.0 + proportion * ((gdouble) area->height / area->width - 1.0);
if (scale <= 1.0)
squeeze = +2.0 * atan (1.0 / scale - 1.0) / G_PI;
else
squeeze = -2.0 * atan (scale - 1.0) / G_PI;
g_object_set (config,
"shape", type,
"x", x / area->width,
"y", y / area->height,
"radius", 2.0 * radius / area->width,
"proportion", proportion,
"squeeze", squeeze,
"rotation", fmod (fmod (angle * 180.0 / G_PI, 360.0) + 360.0,
360.0),
"softness", 1.0 - inner_limit,
"gamma", midpoint < 1.0 ?
MIN (log (0.5) / log (midpoint), MAX_GAMMA) :
MAX_GAMMA,
NULL);
}
static void
config_notify (GObject *config,
const GParamSpec *pspec,
gpointer set_data)
{
PikaControllerFocusCallback set_func;
GeglRectangle *area;
PikaLimitType shape;
gdouble x, y;
gdouble radius;
gdouble proportion;
gdouble squeeze;
gdouble rotation;
gdouble softness;
gdouble gamma;
gdouble aspect_ratio;
set_func = g_object_get_data (G_OBJECT (config), "set-func");
area = g_object_get_data (G_OBJECT (config), "area");
g_object_get (config,
"shape", &shape,
"x", &x,
"y", &y,
"radius", &radius,
"proportion", &proportion,
"squeeze", &squeeze,
"rotation", &rotation,
"softness", &softness,
"gamma", &gamma,
NULL);
aspect_ratio = 1.0 + ((gdouble) area->height / area->width - 1.0) *
proportion;
if (squeeze >= 0.0)
aspect_ratio /= tan (+squeeze * G_PI / 2.0) + 1.0;
else
aspect_ratio *= tan (-squeeze * G_PI / 2.0) + 1.0;
if (aspect_ratio <= 1.0)
aspect_ratio = 1.0 - aspect_ratio;
else
aspect_ratio = 1.0 / aspect_ratio - 1.0;
set_func (set_data, area,
shape,
x * area->width,
y * area->height,
radius * area->width / 2.0,
aspect_ratio,
rotation / 180.0 * G_PI,
1.0 - softness,
pow (0.5, 1.0 / gamma));
}
GtkWidget *
_pika_prop_gui_new_vignette (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *vbox;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (param_specs != NULL, NULL);
g_return_val_if_fail (n_param_specs > 0, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
vbox = _pika_prop_gui_new_generic (config,
param_specs, n_param_specs,
area, context,
create_picker_func,
create_controller_func,
creator);
if (create_controller_func)
{
GCallback set_func;
gpointer set_data;
set_func = create_controller_func (creator,
PIKA_CONTROLLER_TYPE_FOCUS,
_("Vignette: "),
(GCallback) focus_callback,
config,
&set_data);
g_object_set_data (G_OBJECT (config), "set-func", set_func);
g_object_set_data_full (G_OBJECT (config), "area",
g_memdup2 (area, sizeof (GeglRectangle)),
(GDestroyNotify) g_free);
config_notify (config, NULL, set_data);
g_signal_connect (config, "notify",
G_CALLBACK (config_notify),
set_data);
}
return vbox;
}

View File

@ -0,0 +1,40 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui-vignette.h
* Copyright (C) 2020 Ell
*
* 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 __PIKA_PROP_GUI_VIGNETTE_H__
#define __PIKA_PROP_GUI_VIGNETTE_H__
GtkWidget *
_pika_prop_gui_new_vignette (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
#endif /* __PIKA_PROP_GUI_VIGNETTE_H__ */

712
app/propgui/pikapropgui.c Normal file
View File

@ -0,0 +1,712 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui.c
* Copyright (C) 2002-2017 Michael Natterer <mitch@gimp.org>
* Sven Neumann <sven@gimp.org>
*
* 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 <string.h>
#include <gegl.h>
#include <gegl-paramspecs.h>
#include <gtk/gtk.h>
#include "libpikacolor/pikacolor.h"
#include "libpikaconfig/pikaconfig.h"
#include "libpikawidgets/pikawidgets.h"
#include "propgui-types.h"
#include "gegl/pika-gegl-utils.h"
#include "operations/pika-operation-config.h"
#include "core/pikacontext.h"
#include "widgets/pikacolorpanel.h"
#include "widgets/pikamessagebox.h"
#include "widgets/pikapropwidgets.h"
#include "pikapropgui.h"
#include "pikapropgui-channel-mixer.h"
#include "pikapropgui-color-balance.h"
#include "pikapropgui-color-rotate.h"
#include "pikapropgui-color-to-alpha.h"
#include "pikapropgui-convolution-matrix.h"
#include "pikapropgui-diffraction-patterns.h"
#include "pikapropgui-eval.h"
#include "pikapropgui-focus-blur.h"
#include "pikapropgui-generic.h"
#include "pikapropgui-hue-saturation.h"
#include "pikapropgui-motion-blur-circular.h"
#include "pikapropgui-motion-blur-linear.h"
#include "pikapropgui-motion-blur-zoom.h"
#include "pikapropgui-newsprint.h"
#include "pikapropgui-panorama-projection.h"
#include "pikapropgui-recursive-transform.h"
#include "pikapropgui-shadows-highlights.h"
#include "pikapropgui-spiral.h"
#include "pikapropgui-supernova.h"
#include "pikapropgui-utils.h"
#include "pikapropgui-vignette.h"
#include "pika-intl.h"
#define HAS_KEY(p,k,v) pika_gegl_param_spec_has_key (p, k, v)
static gboolean pika_prop_string_to_boolean (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data);
static void pika_prop_config_notify (GObject *config,
GParamSpec *pspec,
GtkWidget *widget);
static void pika_prop_widget_show (GtkWidget *widget,
GObject *config);
static void pika_prop_free_label_ref (GWeakRef *label_ref);
/* public functions */
GtkWidget *
pika_prop_widget_new (GObject *config,
const gchar *property_name,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator,
const gchar **label)
{
GParamSpec *pspec;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
property_name);
return pika_prop_widget_new_from_pspec (config, pspec, area, context,
create_picker_func,
create_controller_func,
creator,
label);
}
GtkWidget *
pika_prop_widget_new_from_pspec (GObject *config,
GParamSpec *pspec,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator,
const gchar **label)
{
GtkWidget *widget = NULL;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (pspec != NULL, NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
g_return_val_if_fail (label != NULL, NULL);
*label = NULL;
if (GEGL_IS_PARAM_SPEC_SEED (pspec))
{
widget = pika_prop_random_seed_new (config, pspec->name);
*label = g_param_spec_get_nick (pspec);
}
else if (G_IS_PARAM_SPEC_INT (pspec) ||
G_IS_PARAM_SPEC_UINT (pspec) ||
G_IS_PARAM_SPEC_FLOAT (pspec) ||
G_IS_PARAM_SPEC_DOUBLE (pspec))
{
gdouble lower;
gdouble upper;
gdouble step;
gdouble page;
gint digits;
if (GEGL_IS_PARAM_SPEC_DOUBLE (pspec))
{
GeglParamSpecDouble *gspec = GEGL_PARAM_SPEC_DOUBLE (pspec);
lower = gspec->ui_minimum;
upper = gspec->ui_maximum;
step = gspec->ui_step_small;
page = gspec->ui_step_big;
digits = gspec->ui_digits;
}
else if (GEGL_IS_PARAM_SPEC_INT (pspec))
{
GeglParamSpecInt *gspec = GEGL_PARAM_SPEC_INT (pspec);
lower = gspec->ui_minimum;
upper = gspec->ui_maximum;
step = gspec->ui_step_small;
page = gspec->ui_step_big;
digits = 0;
}
else
{
gdouble value;
/* Get the min and max for the given property. */
_pika_prop_widgets_get_numeric_values (config, pspec,
&value, &lower, &upper,
G_STRFUNC);
if ((upper - lower <= 1.0) &&
(G_IS_PARAM_SPEC_FLOAT (pspec) ||
G_IS_PARAM_SPEC_DOUBLE (pspec)))
{
step = 0.01;
page = 0.1;
digits = 4;
}
else if ((upper - lower <= 10.0) &&
(G_IS_PARAM_SPEC_FLOAT (pspec) ||
G_IS_PARAM_SPEC_DOUBLE (pspec)))
{
step = 0.1;
page = 1.0;
digits = 3;
}
else
{
step = 1.0;
page = 10.0;
digits = (G_IS_PARAM_SPEC_FLOAT (pspec) ||
G_IS_PARAM_SPEC_DOUBLE (pspec)) ? 2 : 0;
}
}
widget = pika_prop_spin_scale_new (config, pspec->name,
step, page, digits);
if (HAS_KEY (pspec, "unit", "degree") &&
(upper - lower) == 360.0)
{
GtkWidget *hbox;
GtkWidget *dial;
gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (widget), TRUE);
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
dial = pika_prop_angle_dial_new (config, pspec->name);
g_object_set (dial,
"clockwise-angles", HAS_KEY (pspec, "direction", "cw"),
NULL);
gtk_box_pack_start (GTK_BOX (hbox), dial, FALSE, FALSE, 0);
gtk_widget_show (dial);
pika_help_set_help_data (hbox, g_param_spec_get_blurb (pspec), NULL);
pika_prop_gui_bind_label (hbox, widget);
widget = hbox;
}
else if (HAS_KEY (pspec, "unit", "kelvin"))
{
GtkWidget *hbox;
GtkWidget *button;
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
gtk_widget_show (widget);
button = pika_prop_kelvin_presets_new (config, pspec->name);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
pika_help_set_help_data (hbox, g_param_spec_get_blurb (pspec), NULL);
pika_prop_gui_bind_label (hbox, widget);
widget = hbox;
}
else
{
pika_prop_gui_bind_label (widget, widget);
if (area &&
(HAS_KEY (pspec, "unit", "pixel-coordinate") ||
HAS_KEY (pspec, "unit", "pixel-distance")) &&
(HAS_KEY (pspec, "axis", "x") ||
HAS_KEY (pspec, "axis", "y")))
{
gdouble min = lower;
gdouble max = upper;
if (HAS_KEY (pspec, "unit", "pixel-coordinate"))
{
/* limit pixel coordinate scales to the actual area */
gint off_x = area->x;
gint off_y = area->y;
if (HAS_KEY (pspec, "axis", "x"))
{
min = MAX (lower, off_x);
max = MIN (upper, off_x + area->width);
}
else if (HAS_KEY (pspec, "axis","y"))
{
min = MAX (lower, off_y);
max = MIN (upper, off_y + area->height);
}
}
else if (HAS_KEY (pspec, "unit", "pixel-distance"))
{
/* limit pixel distance scales to the same value on the
* x and y axes, so linked values have the same range,
* we use MAX (width, height), see issue #2540
*/
max = MIN (upper, MAX (area->width, area->height));
}
pika_spin_scale_set_scale_limits (PIKA_SPIN_SCALE (widget),
min, max);
}
}
}
else if (G_IS_PARAM_SPEC_STRING (pspec))
{
*label = g_param_spec_get_nick (pspec);
if (PIKA_IS_PARAM_SPEC_CONFIG_PATH (pspec))
{
widget =
pika_prop_file_chooser_button_new (config, pspec->name,
g_param_spec_get_nick (pspec),
GTK_FILE_CHOOSER_ACTION_OPEN);
}
else if (HAS_KEY (pspec, "multiline", "true"))
{
GtkTextBuffer *buffer;
GtkWidget *view;
buffer = pika_prop_text_buffer_new (config, pspec->name, -1);
view = gtk_text_view_new_with_buffer (buffer);
g_object_unref (buffer);
widget = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_size_request (widget, -1, 150);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (widget),
GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (widget), view);
gtk_widget_show (view);
}
else if (HAS_KEY (pspec, "error", "true"))
{
GtkWidget *l;
widget = pika_message_box_new (PIKA_ICON_MASCOT_EEK);
pika_message_box_set_primary_text (PIKA_MESSAGE_BOX (widget), "%s",
*label);
pika_message_box_set_text (PIKA_MESSAGE_BOX (widget), "%s", "");
l = PIKA_MESSAGE_BOX (widget)->label[1];
g_object_bind_property (config, pspec->name,
l, "label",
G_BINDING_SYNC_CREATE);
g_object_bind_property_full (config, pspec->name,
widget, "visible",
G_BINDING_SYNC_CREATE,
pika_prop_string_to_boolean,
NULL,
NULL, NULL);
*label = NULL;
}
else
{
widget = pika_prop_entry_new (config, pspec->name, -1);
}
}
else if (G_IS_PARAM_SPEC_BOOLEAN (pspec))
{
widget = pika_prop_check_button_new (config, pspec->name,
g_param_spec_get_nick (pspec));
pika_prop_gui_bind_label (widget, widget);
}
else if (G_IS_PARAM_SPEC_ENUM (pspec))
{
widget = pika_prop_enum_combo_box_new (config, pspec->name, 0, 0);
pika_int_combo_box_set_label (PIKA_INT_COMBO_BOX (widget),
g_param_spec_get_nick (pspec));
pika_prop_gui_bind_label (widget, widget);
}
else if (PIKA_IS_PARAM_SPEC_RGB (pspec))
{
gboolean has_alpha;
GtkWidget *button;
has_alpha = pika_param_spec_rgb_has_alpha (pspec);
widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
button = pika_prop_color_button_new (config, pspec->name,
g_param_spec_get_nick (pspec),
128, 24,
has_alpha ?
PIKA_COLOR_AREA_SMALL_CHECKS :
PIKA_COLOR_AREA_FLAT);
pika_color_button_set_update (PIKA_COLOR_BUTTON (button), TRUE);
pika_color_panel_set_context (PIKA_COLOR_PANEL (button), context);
gtk_box_pack_start (GTK_BOX (widget), button, TRUE, TRUE, 0);
gtk_widget_show (button);
pika_prop_gui_bind_tooltip (button, widget);
if (create_picker_func)
{
button = create_picker_func (creator,
pspec->name,
PIKA_ICON_COLOR_PICKER_GRAY,
_("Pick color from the image"),
/* pick_abyss = */ FALSE,
NULL, NULL);
gtk_box_pack_start (GTK_BOX (widget), button, FALSE, FALSE, 0);
gtk_widget_show (button);
}
*label = g_param_spec_get_nick (pspec);
}
else
{
g_warning ("%s: not supported: %s (%s)\n", G_STRFUNC,
g_type_name (G_TYPE_FROM_INSTANCE (pspec)), pspec->name);
}
/* if we have any keys for dynamic properties, listen to config's notify
* signal, and update the properties accordingly.
*/
if (gegl_param_spec_get_property_key (pspec, "sensitive") ||
gegl_param_spec_get_property_key (pspec, "visible") ||
gegl_param_spec_get_property_key (pspec, "label") ||
gegl_param_spec_get_property_key (pspec, "description"))
{
g_object_set_data (G_OBJECT (widget), "pika-prop-pspec", pspec);
g_signal_connect_object (config, "notify",
G_CALLBACK (pika_prop_config_notify),
widget, 0);
if (gegl_param_spec_get_property_key (pspec, "visible"))
{
/* a bit of a hack: if we have a dynamic "visible" property key,
* connect to the widget's "show" signal, so that we can intercept
* our caller's gtk_widget_show() call, and keep the widget hidden if
* necessary.
*/
g_signal_connect (widget, "show",
G_CALLBACK (pika_prop_widget_show),
config);
}
/* update all the properties now */
pika_prop_config_notify (config, NULL, widget);
}
gtk_widget_show (widget);
return widget;
}
typedef GtkWidget * (* PikaPropGuiNewFunc) (GObject *config,
GParamSpec **param_specs,
guint n_param_specs,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator);
static const struct
{
const gchar *config_type;
PikaPropGuiNewFunc gui_new_func;
}
gui_new_funcs[] =
{
{ "PikaColorBalanceConfig",
_pika_prop_gui_new_color_balance },
{ "PikaHueSaturationConfig",
_pika_prop_gui_new_hue_saturation },
{ "PikaGegl-gegl-color-rotate-config",
_pika_prop_gui_new_color_rotate },
{ "PikaGegl-gegl-color-to-alpha-config",
_pika_prop_gui_new_color_to_alpha },
{ "PikaGegl-gegl-convolution-matrix-config",
_pika_prop_gui_new_convolution_matrix },
{ "PikaGegl-gegl-channel-mixer-config",
_pika_prop_gui_new_channel_mixer },
{ "PikaGegl-gegl-diffraction-patterns-config",
_pika_prop_gui_new_diffraction_patterns },
{ "PikaGegl-gegl-focus-blur-config",
_pika_prop_gui_new_focus_blur },
{ "PikaGegl-gegl-motion-blur-circular-config",
_pika_prop_gui_new_motion_blur_circular },
{ "PikaGegl-gegl-motion-blur-linear-config",
_pika_prop_gui_new_motion_blur_linear },
{ "PikaGegl-gegl-motion-blur-zoom-config",
_pika_prop_gui_new_motion_blur_zoom },
{ "PikaGegl-gegl-newsprint-config",
_pika_prop_gui_new_newsprint },
{ "PikaGegl-gegl-panorama-projection-config",
_pika_prop_gui_new_panorama_projection },
{ "PikaGegl-gegl-recursive-transform-config",
_pika_prop_gui_new_recursive_transform },
{ "PikaGegl-gegl-shadows-highlights-config",
_pika_prop_gui_new_shadows_highlights },
{ "PikaGegl-gegl-spiral-config",
_pika_prop_gui_new_spiral },
{ "PikaGegl-gegl-supernova-config",
_pika_prop_gui_new_supernova },
{ "PikaGegl-gegl-vignette-config",
_pika_prop_gui_new_vignette },
{ NULL,
_pika_prop_gui_new_generic }
};
GtkWidget *
pika_prop_gui_new (GObject *config,
GType owner_type,
GParamFlags flags,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker_func,
PikaCreateControllerFunc create_controller_func,
gpointer creator)
{
GtkWidget *gui = NULL;
GParamSpec **param_specs;
guint n_param_specs;
g_return_val_if_fail (G_IS_OBJECT (config), NULL);
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
param_specs = pika_operation_config_list_properties (config,
owner_type, flags,
&n_param_specs);
if (param_specs)
{
const gchar *config_type_name = G_OBJECT_TYPE_NAME (config);
gint i;
for (i = 0; i < G_N_ELEMENTS (gui_new_funcs); i++)
{
if (! gui_new_funcs[i].config_type ||
! strcmp (gui_new_funcs[i].config_type, config_type_name))
{
g_printerr ("GUI new func match: %s\n",
gui_new_funcs[i].config_type ?
gui_new_funcs[i].config_type : "generic fallback");
gui = gui_new_funcs[i].gui_new_func (config,
param_specs, n_param_specs,
area,
context,
create_picker_func,
create_controller_func,
creator);
break;
}
}
g_free (param_specs);
}
else
{
gui = gtk_label_new (_("This operation has no editable properties"));
pika_label_set_attributes (GTK_LABEL (gui),
PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC,
-1);
g_object_set (gui,
"margin-top", 4,
"margin-bottom", 4,
NULL);
}
gtk_widget_show (gui);
return gui;
}
void
pika_prop_gui_bind_container (GtkWidget *source,
GtkWidget *target)
{
g_object_bind_property (source, "sensitive",
target, "sensitive",
G_BINDING_SYNC_CREATE);
g_object_bind_property (source, "visible",
target, "visible",
G_BINDING_SYNC_CREATE);
}
void
pika_prop_gui_bind_label (GtkWidget *source,
GtkWidget *target)
{
GWeakRef *label_ref;
const gchar *label;
/* we want to update "target"'s "label" property whenever the label
* expression associated with "source" is reevaluated, however, "source"
* might not itself have a "label" property we can bind to. just keep around
* a reference to "target", and update its label manually.
*/
g_return_if_fail (g_object_get_data (G_OBJECT (source),
"pika-prop-label-ref") == NULL);
label_ref = g_slice_new (GWeakRef);
g_weak_ref_init (label_ref, target);
g_object_set_data_full (G_OBJECT (source),
"pika-prop-label-ref", label_ref,
(GDestroyNotify) pika_prop_free_label_ref);
label = g_object_get_data (G_OBJECT (source), "pika-prop-label");
if (label)
g_object_set (target, "label", label, NULL);
/* note that "source" might be its own label widget, in which case there's no
* need to bind the rest of the properties.
*/
if (source != target)
pika_prop_gui_bind_tooltip (source, target);
}
void
pika_prop_gui_bind_tooltip (GtkWidget *source,
GtkWidget *target)
{
g_object_bind_property (source, "tooltip-text",
target, "tooltip-text",
G_BINDING_SYNC_CREATE);
}
/* private functions */
static gboolean
pika_prop_string_to_boolean (GBinding *binding,
const GValue *from_value,
GValue *to_value,
gpointer user_data)
{
const gchar *string = g_value_get_string (from_value);
g_value_set_boolean (to_value, string && *string);
return TRUE;
}
static void
pika_prop_config_notify (GObject *config,
GParamSpec *pspec,
GtkWidget *widget)
{
GParamSpec *widget_pspec;
GWeakRef *label_ref;
GtkWidget *label_widget;
gboolean sensitive;
gboolean visible;
gchar *label;
gchar *description;
widget_pspec = g_object_get_data (G_OBJECT (widget), "pika-prop-pspec");
label_ref = g_object_get_data (G_OBJECT (widget), "pika-prop-label-ref");
if (label_ref)
label_widget = g_weak_ref_get (label_ref);
else
label_widget = NULL;
sensitive = pika_prop_eval_boolean (config, widget_pspec, "sensitive", TRUE);
visible = pika_prop_eval_boolean (config, widget_pspec, "visible", TRUE);
label = pika_prop_eval_string (config, widget_pspec, "label",
g_param_spec_get_nick (widget_pspec));
description = pika_prop_eval_string (config, widget_pspec, "description",
g_param_spec_get_blurb (widget_pspec));
/* we store the label in (and pass ownership over it to) the widget's
* "pika-prop-label" key, so that we can use it to initialize the label
* widget's label in pika_prop_gui_bind_label() upon binding.
*/
g_object_set_data_full (G_OBJECT (widget), "pika-prop-label", label, g_free);
g_signal_handlers_block_by_func (widget,
pika_prop_widget_show, config);
gtk_widget_set_sensitive (widget, sensitive);
gtk_widget_set_visible (widget, visible);
if (label_widget) g_object_set (label_widget, "label", label, NULL);
pika_help_set_help_data (widget, description, NULL);
g_signal_handlers_unblock_by_func (widget,
pika_prop_widget_show, config);
g_free (description);
if (label_widget)
g_object_unref (label_widget);
}
static void
pika_prop_widget_show (GtkWidget *widget,
GObject *config)
{
GParamSpec *widget_pspec;
gboolean visible;
widget_pspec = g_object_get_data (G_OBJECT (widget), "pika-prop-pspec");
visible = pika_prop_eval_boolean (config, widget_pspec, "visible", TRUE);
gtk_widget_set_visible (widget, visible);
}
static void
pika_prop_free_label_ref (GWeakRef *label_ref)
{
g_weak_ref_clear (label_ref);
g_slice_free (GWeakRef, label_ref);
}

64
app/propgui/pikapropgui.h Normal file
View File

@ -0,0 +1,64 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikapropgui.h
* Copyright (C) 2002-2017 Michael Natterer <mitch@gimp.org>
*
* 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 __PIKA_PROP_GUI_H__
#define __PIKA_PROP_GUI_H__
/* A view on all of an object's properties */
GtkWidget * pika_prop_widget_new (GObject *config,
const gchar *property_name,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker,
PikaCreateControllerFunc create_controller,
gpointer creator,
const gchar **label);
GtkWidget * pika_prop_widget_new_from_pspec (GObject *config,
GParamSpec *pspec,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker,
PikaCreateControllerFunc create_controller,
gpointer creator,
const gchar **label);
GtkWidget * pika_prop_gui_new (GObject *config,
GType owner_type,
GParamFlags flags,
GeglRectangle *area,
PikaContext *context,
PikaCreatePickerFunc create_picker,
PikaCreateControllerFunc create_controller,
gpointer creator);
void pika_prop_gui_bind_container (GtkWidget *source,
GtkWidget *target);
void pika_prop_gui_bind_label (GtkWidget *source,
GtkWidget *target);
void pika_prop_gui_bind_tooltip (GtkWidget *source,
GtkWidget *target);
#endif /* __PIKA_PROP_GUI_H__ */

149
app/propgui/propgui-types.h Normal file
View File

@ -0,0 +1,149 @@
/* PIKA - Photo and Image Kooker Application
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
*
* Original copyright, applying to most contents (license remains unchanged):
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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 __PROPGUI_TYPES_H__
#define __PROPGUI_TYPES_H__
#include "display/display-enums.h"
#include "widgets/widgets-types.h"
/* enums, move to propgui-enums.h if we get more */
typedef enum
{
PIKA_CONTROLLER_TYPE_LINE,
PIKA_CONTROLLER_TYPE_SLIDER_LINE,
PIKA_CONTROLLER_TYPE_TRANSFORM_GRID,
PIKA_CONTROLLER_TYPE_TRANSFORM_GRIDS,
PIKA_CONTROLLER_TYPE_GYROSCOPE,
PIKA_CONTROLLER_TYPE_FOCUS
} PikaControllerType;
/* structs */
typedef struct
{
gdouble value; /* slider value */
gdouble min; /* minimal allowable slider value */
gdouble max; /* maximal allowable slider value */
gboolean visible : 1; /* slider is visible */
gboolean selectable : 1; /* slider is selectable */
gboolean movable : 1; /* slider movable */
gboolean removable : 1; /* slider is removable */
gboolean autohide : 1; /* whether to autohide the slider */
PikaHandleType type; /* slider handle type */
gdouble size; /* slider handle size, as a fraction of *
* the default size */
gpointer data; /* user data */
} PikaControllerSlider;
#define PIKA_CONTROLLER_SLIDER_DEFAULT \
((const PikaControllerSlider) { \
.value = 0.0, \
.min = 0.0, \
.max = 1.0, \
\
.visible = TRUE, \
.selectable = TRUE, \
.movable = TRUE, \
.removable = FALSE, \
\
.autohide = FALSE, \
.type = PIKA_HANDLE_FILLED_DIAMOND, \
.size = 1.0, \
\
.data = NULL \
})
/* function types */
typedef void (* PikaPickerCallback) (gpointer data,
gpointer identifier,
gdouble x,
gdouble y,
const Babl *sample_format,
const PikaRGB *color);
typedef void (* PikaControllerLineCallback) (gpointer data,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2);
typedef void (* PikaControllerSliderLineCallback) (gpointer data,
GeglRectangle *area,
gdouble x1,
gdouble y1,
gdouble x2,
gdouble y2,
const PikaControllerSlider *sliders,
gint n_sliders);
typedef void (* PikaControllerTransformGridCallback) (gpointer data,
GeglRectangle *area,
const PikaMatrix3 *transform);
typedef void (* PikaControllerTransformGridsCallback) (gpointer data,
GeglRectangle *area,
const PikaMatrix3 *transforms,
gint n_transforms);
typedef void (* PikaControllerGyroscopeCallback) (gpointer data,
GeglRectangle *area,
gdouble yaw,
gdouble pitch,
gdouble roll,
gdouble zoom,
gboolean invert);
typedef void (* PikaControllerFocusCallback) (gpointer data,
GeglRectangle *area,
PikaLimitType type,
gdouble x,
gdouble y,
gdouble radius,
gdouble aspect_ratio,
gdouble angle,
gdouble inner_limit,
gdouble midpoint);
typedef GtkWidget * (* PikaCreatePickerFunc) (gpointer creator,
const gchar *property_name,
const gchar *icon_name,
const gchar *tooltip,
gboolean pick_abyss,
PikaPickerCallback callback,
gpointer callback_data);
typedef GCallback (* PikaCreateControllerFunc) (gpointer creator,
PikaControllerType controller_type,
const gchar *status_title,
GCallback callback,
gpointer callback_data,
gpointer *set_func_data);
#endif /* __PROPGUI_TYPES_H__ */