summaryrefslogtreecommitdiffstats
path: root/app/propgui/gimppropgui-newsprint.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--app/propgui/gimppropgui-newsprint.c444
1 files changed, 444 insertions, 0 deletions
diff --git a/app/propgui/gimppropgui-newsprint.c b/app/propgui/gimppropgui-newsprint.c
new file mode 100644
index 0000000..214c534
--- /dev/null
+++ b/app/propgui/gimppropgui-newsprint.c
@@ -0,0 +1,444 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
+ *
+ * gimppropgui-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 "libgimpmath/gimpmath.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "propgui-types.h"
+
+#include "core/gimpcontext.h"
+
+#include "gimppropgui.h"
+#include "gimppropgui-generic.h"
+#include "gimppropgui-newsprint.h"
+
+#include "gimp-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 *
+_gimp_prop_gui_new_newsprint (GObject *config,
+ GParamSpec **param_specs,
+ guint n_param_specs,
+ GeglRectangle *area,
+ GimpContext *context,
+ GimpCreatePickerFunc create_picker_func,
+ GimpCreateControllerFunc 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 (GIMP_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 = gimp_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 = _gimp_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 = gimp_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 = _gimp_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 = gimp_frame_new (_("Quality"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ vbox = _gimp_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 = gimp_frame_new (_("Effects"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ vbox = _gimp_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));
+ }
+}