Updated new files from upstream
This commit is contained in:
parent
3bbdd873ef
commit
852cbfc1fb
|
@ -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-2003 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is auto-generated by pdbgen.pl. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "stamp-pdbgen.h"
|
||||
|
||||
#include <gegl.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
|
||||
#include "pdb-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikadatafactory.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
|
||||
#include "pikapdb.h"
|
||||
#include "pikaprocedure.h"
|
||||
#include "internal-procs.h"
|
||||
|
||||
|
||||
static PikaValueArray *
|
||||
drawables_popup_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
const gchar *callback;
|
||||
const gchar *popup_title;
|
||||
const gchar *drawable_type;
|
||||
PikaDrawable *initial_drawable;
|
||||
GBytes *parent_window;
|
||||
|
||||
callback = g_value_get_string (pika_value_array_index (args, 0));
|
||||
popup_title = g_value_get_string (pika_value_array_index (args, 1));
|
||||
drawable_type = g_value_get_string (pika_value_array_index (args, 2));
|
||||
initial_drawable = g_value_get_object (pika_value_array_index (args, 3));
|
||||
parent_window = g_value_get_boxed (pika_value_array_index (args, 4));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (pika->no_interface ||
|
||||
! pika_pdb_lookup_procedure (pika->pdb, callback) ||
|
||||
! pika_pdb_dialog_new (pika, context, progress,
|
||||
g_type_from_name (drawable_type),
|
||||
parent_window, popup_title, callback,
|
||||
PIKA_OBJECT (initial_drawable),
|
||||
NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
static PikaValueArray *
|
||||
drawables_close_popup_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
const gchar *callback;
|
||||
|
||||
callback = g_value_get_string (pika_value_array_index (args, 0));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (pika->no_interface ||
|
||||
! pika_pdb_lookup_procedure (pika->pdb, callback) ||
|
||||
! pika_pdb_dialog_close (pika, PIKA_TYPE_DRAWABLE, callback))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
static PikaValueArray *
|
||||
drawables_set_popup_invoker (PikaProcedure *procedure,
|
||||
Pika *pika,
|
||||
PikaContext *context,
|
||||
PikaProgress *progress,
|
||||
const PikaValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
const gchar *callback;
|
||||
PikaDrawable *drawable;
|
||||
|
||||
callback = g_value_get_string (pika_value_array_index (args, 0));
|
||||
drawable = g_value_get_object (pika_value_array_index (args, 1));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (pika->no_interface ||
|
||||
! pika_pdb_lookup_procedure (pika->pdb, callback) ||
|
||||
! pika_pdb_dialog_set (pika, PIKA_TYPE_DRAWABLE, callback, PIKA_OBJECT (drawable), NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return pika_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
void
|
||||
register_drawable_select_procs (PikaPDB *pdb)
|
||||
{
|
||||
PikaProcedure *procedure;
|
||||
|
||||
/*
|
||||
* pika-drawables-popup
|
||||
*/
|
||||
procedure = pika_procedure_new (drawables_popup_invoker);
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure),
|
||||
"pika-drawables-popup");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Invokes the drawable selection dialog.",
|
||||
"Opens a dialog letting a user choose an drawable.",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Jehan",
|
||||
"Jehan",
|
||||
"2023");
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("callback",
|
||||
"callback",
|
||||
"The callback PDB proc to call when user chooses an drawable",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("popup-title",
|
||||
"popup title",
|
||||
"Title of the drawable selection dialog",
|
||||
FALSE, FALSE, FALSE,
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("drawable-type",
|
||||
"drawable type",
|
||||
"The name of the PIKA_TYPE_DRAWABLE subtype",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_drawable ("initial-drawable",
|
||||
"initial drawable",
|
||||
"The drawable to set as the initial choice",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
g_param_spec_boxed ("parent-window",
|
||||
"parent window",
|
||||
"An optional parent window handle for the popup to be set transient to",
|
||||
G_TYPE_BYTES,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* pika-drawables-close-popup
|
||||
*/
|
||||
procedure = pika_procedure_new (drawables_close_popup_invoker);
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure),
|
||||
"pika-drawables-close-popup");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Close the drawable selection dialog.",
|
||||
"Closes an open drawable selection dialog.",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Jehan",
|
||||
"Jehan",
|
||||
"2023");
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("callback",
|
||||
"callback",
|
||||
"The name of the callback registered for this pop-up",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* pika-drawables-set-popup
|
||||
*/
|
||||
procedure = pika_procedure_new (drawables_set_popup_invoker);
|
||||
pika_object_set_static_name (PIKA_OBJECT (procedure),
|
||||
"pika-drawables-set-popup");
|
||||
pika_procedure_set_static_help (procedure,
|
||||
"Sets the selected drawable in a drawable selection dialog.",
|
||||
"Sets the selected drawable in a drawable selection dialog.",
|
||||
NULL);
|
||||
pika_procedure_set_static_attribution (procedure,
|
||||
"Jehan",
|
||||
"Jehan",
|
||||
"2023");
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_string ("callback",
|
||||
"callback",
|
||||
"The name of the callback registered for this pop-up",
|
||||
FALSE, FALSE, TRUE,
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
pika_procedure_add_argument (procedure,
|
||||
pika_param_spec_drawable ("drawable",
|
||||
"drawable",
|
||||
"The drawable to set as selected",
|
||||
FALSE,
|
||||
PIKA_PARAM_READWRITE | PIKA_PARAM_NO_VALIDATE));
|
||||
pika_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
}
|
|
@ -0,0 +1,589 @@
|
|||
/* 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
|
||||
*
|
||||
* pikapickablechooser.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* 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 <gdk/gdkkeysyms.h>
|
||||
|
||||
#include "libpikabase/pikabase.h"
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikachannel.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikaimage.h"
|
||||
#include "core/pikalayer.h"
|
||||
#include "core/pikapickable.h"
|
||||
#include "core/pikaviewable.h"
|
||||
|
||||
#include "pikacontainertreeview.h"
|
||||
#include "pikacontainerview.h"
|
||||
#include "pikapickablechooser.h"
|
||||
#include "pikaviewrenderer.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
ACTIVATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CONTEXT,
|
||||
PROP_PICKABLE_TYPE,
|
||||
PROP_PICKABLE,
|
||||
PROP_VIEW_SIZE,
|
||||
PROP_VIEW_BORDER_WIDTH
|
||||
};
|
||||
|
||||
struct _PikaPickableChooserPrivate
|
||||
{
|
||||
GType pickable_type;
|
||||
PikaPickable *pickable;
|
||||
PikaContext *context;
|
||||
|
||||
gint view_size;
|
||||
gint view_border_width;
|
||||
|
||||
GtkWidget *image_view;
|
||||
GtkWidget *layer_view;
|
||||
GtkWidget *channel_view;
|
||||
GtkWidget *layer_label;
|
||||
};
|
||||
|
||||
|
||||
static void pika_pickable_chooser_constructed (GObject *object);
|
||||
static void pika_pickable_chooser_finalize (GObject *object);
|
||||
static void pika_pickable_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void pika_pickable_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void pika_pickable_chooser_image_changed (PikaContext *context,
|
||||
PikaImage *image,
|
||||
PikaPickableChooser *chooser);
|
||||
static void pika_pickable_chooser_item_activate (PikaContainerView *view,
|
||||
PikaPickable *pickable,
|
||||
gpointer unused,
|
||||
PikaPickableChooser *chooser);
|
||||
static void pika_pickable_chooser_items_selected (PikaContainerView *view,
|
||||
GList *items,
|
||||
GList *paths,
|
||||
PikaPickableChooser *chooser);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (PikaPickableChooser, pika_pickable_chooser, GTK_TYPE_FRAME)
|
||||
|
||||
#define parent_class pika_pickable_chooser_parent_class
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_class_init (PikaPickableChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = pika_pickable_chooser_constructed;
|
||||
object_class->finalize = pika_pickable_chooser_finalize;
|
||||
object_class->get_property = pika_pickable_chooser_get_property;
|
||||
object_class->set_property = pika_pickable_chooser_set_property;
|
||||
|
||||
/**
|
||||
* PikaPickableChooser::activate:
|
||||
* @chooser:
|
||||
*
|
||||
* Emitted when a pickable is activated, which is mostly forwarding when
|
||||
* "activate-item" signal is emitted from any of either the image, layer or
|
||||
* channel view. E.g. this happens when one double-click on one of the
|
||||
* pickables.
|
||||
*/
|
||||
signals[ACTIVATE] =
|
||||
g_signal_new ("activate",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (PikaPickableChooserClass, activate),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
PIKA_TYPE_OBJECT);
|
||||
|
||||
g_object_class_install_property (object_class, PROP_CONTEXT,
|
||||
g_param_spec_object ("context",
|
||||
NULL, NULL,
|
||||
PIKA_TYPE_CONTEXT,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PICKABLE_TYPE,
|
||||
g_param_spec_gtype ("pickable-type",
|
||||
NULL, NULL,
|
||||
PIKA_TYPE_PICKABLE,
|
||||
PIKA_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PICKABLE,
|
||||
g_param_spec_object ("pickable",
|
||||
NULL, NULL,
|
||||
PIKA_TYPE_PICKABLE,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_VIEW_SIZE,
|
||||
g_param_spec_int ("view-size",
|
||||
NULL, NULL,
|
||||
1, PIKA_VIEWABLE_MAX_PREVIEW_SIZE,
|
||||
PIKA_VIEW_SIZE_MEDIUM,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_VIEW_BORDER_WIDTH,
|
||||
g_param_spec_int ("view-border-width",
|
||||
NULL, NULL,
|
||||
0,
|
||||
PIKA_VIEW_MAX_BORDER_WIDTH,
|
||||
1,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_init (PikaPickableChooser *chooser)
|
||||
{
|
||||
chooser->priv = pika_pickable_chooser_get_instance_private (chooser);
|
||||
|
||||
chooser->priv->view_size = PIKA_VIEW_SIZE_SMALL;
|
||||
chooser->priv->view_border_width = 1;
|
||||
|
||||
chooser->priv->layer_view = NULL;
|
||||
chooser->priv->channel_view = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_constructed (GObject *object)
|
||||
{
|
||||
PikaPickableChooser *chooser = PIKA_PICKABLE_CHOOSER (object);
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *notebook;
|
||||
PikaImage *image;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
pika_assert (PIKA_IS_CONTEXT (chooser->priv->context));
|
||||
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (chooser), GTK_SHADOW_OUT);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
|
||||
gtk_container_add (GTK_CONTAINER (chooser), hbox);
|
||||
gtk_widget_show (hbox);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
label = gtk_label_new (_("Images"));
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
chooser->priv->image_view =
|
||||
pika_container_tree_view_new (chooser->priv->context->pika->images,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
pika_container_box_set_size_request (PIKA_CONTAINER_BOX (chooser->priv->image_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), chooser->priv->image_view, TRUE, TRUE, 0);
|
||||
gtk_widget_show (chooser->priv->image_view);
|
||||
|
||||
g_signal_connect_object (chooser->priv->image_view, "activate-item",
|
||||
G_CALLBACK (pika_pickable_chooser_item_activate),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->image_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
|
||||
gtk_widget_show (vbox);
|
||||
|
||||
chooser->priv->layer_label = label =
|
||||
gtk_label_new (_("Select an image in the left pane"));
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_show (label);
|
||||
|
||||
notebook = gtk_notebook_new ();
|
||||
gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
|
||||
gtk_widget_show (notebook);
|
||||
|
||||
if (g_type_is_a (PIKA_TYPE_LAYER, chooser->priv->pickable_type))
|
||||
{
|
||||
chooser->priv->layer_view =
|
||||
pika_container_tree_view_new (NULL,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (PIKA_CONTAINER_TREE_VIEW (chooser->priv->layer_view)->view),
|
||||
TRUE);
|
||||
pika_container_box_set_size_request (PIKA_CONTAINER_BOX (chooser->priv->layer_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
chooser->priv->layer_view,
|
||||
gtk_label_new (_("Layers")));
|
||||
gtk_widget_show (chooser->priv->layer_view);
|
||||
|
||||
g_signal_connect_object (chooser->priv->layer_view, "activate-item",
|
||||
G_CALLBACK (pika_pickable_chooser_item_activate),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->layer_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
if (g_type_is_a (PIKA_TYPE_CHANNEL, chooser->priv->pickable_type))
|
||||
{
|
||||
chooser->priv->channel_view =
|
||||
pika_container_tree_view_new (NULL,
|
||||
chooser->priv->context,
|
||||
chooser->priv->view_size,
|
||||
chooser->priv->view_border_width);
|
||||
pika_container_box_set_size_request (PIKA_CONTAINER_BOX (chooser->priv->channel_view),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width),
|
||||
4 * (chooser->priv->view_size +
|
||||
2 * chooser->priv->view_border_width));
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
|
||||
chooser->priv->channel_view,
|
||||
gtk_label_new (_("Channels")));
|
||||
gtk_widget_show (chooser->priv->channel_view);
|
||||
|
||||
g_signal_connect_object (chooser->priv->channel_view, "activate-item",
|
||||
G_CALLBACK (pika_pickable_chooser_item_activate),
|
||||
G_OBJECT (chooser), 0);
|
||||
g_signal_connect_object (chooser->priv->channel_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
g_signal_connect_object (chooser->priv->context, "image-changed",
|
||||
G_CALLBACK (pika_pickable_chooser_image_changed),
|
||||
G_OBJECT (chooser), 0);
|
||||
|
||||
image = pika_context_get_image (chooser->priv->context);
|
||||
pika_pickable_chooser_image_changed (chooser->priv->context, image, chooser);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_finalize (GObject *object)
|
||||
{
|
||||
PikaPickableChooser *chooser = PIKA_PICKABLE_CHOOSER (object);
|
||||
|
||||
g_clear_object (&chooser->priv->pickable);
|
||||
g_clear_object (&chooser->priv->context);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaPickableChooser *chooser = PIKA_PICKABLE_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
if (chooser->priv->context)
|
||||
g_object_unref (chooser->priv->context);
|
||||
chooser->priv->context = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_SIZE:
|
||||
chooser->priv->view_size = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_BORDER_WIDTH:
|
||||
chooser->priv->view_border_width = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
case PROP_PICKABLE_TYPE:
|
||||
g_return_if_fail (g_value_get_gtype (value) == PIKA_TYPE_LAYER ||
|
||||
g_value_get_gtype (value) == PIKA_TYPE_CHANNEL ||
|
||||
g_value_get_gtype (value) == PIKA_TYPE_DRAWABLE ||
|
||||
g_value_get_gtype (value) == PIKA_TYPE_IMAGE ||
|
||||
g_value_get_gtype (value) == PIKA_TYPE_PICKABLE);
|
||||
chooser->priv->pickable_type = g_value_get_gtype (value);
|
||||
break;
|
||||
|
||||
case PROP_PICKABLE:
|
||||
g_return_if_fail (g_value_get_object (value) == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (g_value_get_object (value)),
|
||||
chooser->priv->pickable_type));
|
||||
pika_pickable_chooser_set_pickable (chooser, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaPickableChooser *chooser = PIKA_PICKABLE_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_CONTEXT:
|
||||
g_value_set_object (value, chooser->priv->context);
|
||||
break;
|
||||
|
||||
case PROP_PICKABLE_TYPE:
|
||||
g_value_set_gtype (value, chooser->priv->pickable_type);
|
||||
break;
|
||||
|
||||
case PROP_PICKABLE:
|
||||
g_value_set_object (value, chooser->priv->pickable);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_SIZE:
|
||||
g_value_set_int (value, chooser->priv->view_size);
|
||||
break;
|
||||
|
||||
case PROP_VIEW_BORDER_WIDTH:
|
||||
g_value_set_int (value, chooser->priv->view_border_width);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
pika_pickable_chooser_new (PikaContext *context,
|
||||
GType pickable_type,
|
||||
gint view_size,
|
||||
gint view_border_width)
|
||||
{
|
||||
g_return_val_if_fail (PIKA_IS_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (view_size > 0 &&
|
||||
view_size <= PIKA_VIEWABLE_MAX_POPUP_SIZE, NULL);
|
||||
g_return_val_if_fail (view_border_width >= 0 &&
|
||||
view_border_width <= PIKA_VIEW_MAX_BORDER_WIDTH,
|
||||
NULL);
|
||||
|
||||
return g_object_new (PIKA_TYPE_PICKABLE_CHOOSER,
|
||||
"context", context,
|
||||
"pickable-type", pickable_type,
|
||||
"view-size", view_size,
|
||||
"view-border-width", view_border_width,
|
||||
NULL);
|
||||
}
|
||||
|
||||
PikaPickable *
|
||||
pika_pickable_chooser_get_pickable (PikaPickableChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (PIKA_IS_PICKABLE_CHOOSER (chooser), NULL);
|
||||
|
||||
return chooser->priv->pickable;
|
||||
}
|
||||
|
||||
void
|
||||
pika_pickable_chooser_set_pickable (PikaPickableChooser *chooser,
|
||||
PikaPickable *pickable)
|
||||
{
|
||||
if (! gtk_widget_in_destruction (GTK_WIDGET (chooser)))
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->image_view,
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
chooser);
|
||||
if (chooser->priv->layer_view != NULL)
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->layer_view,
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
chooser);
|
||||
else
|
||||
g_return_if_fail (! PIKA_IS_LAYER (pickable));
|
||||
|
||||
if (chooser->priv->channel_view != NULL)
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->channel_view,
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
chooser);
|
||||
else
|
||||
g_return_if_fail (! PIKA_IS_CHANNEL (pickable));
|
||||
|
||||
if (PIKA_IS_IMAGE (pickable))
|
||||
{
|
||||
pika_container_view_select_item (PIKA_CONTAINER_VIEW (chooser->priv->image_view),
|
||||
PIKA_VIEWABLE (pickable));
|
||||
pika_context_set_image (chooser->priv->context, PIKA_IMAGE (pickable));
|
||||
}
|
||||
else if (PIKA_IS_LAYER (pickable))
|
||||
{
|
||||
pika_context_set_image (chooser->priv->context, pika_item_get_image (PIKA_ITEM (pickable)));
|
||||
pika_container_view_select_item (PIKA_CONTAINER_VIEW (chooser->priv->layer_view),
|
||||
PIKA_VIEWABLE (pickable));
|
||||
}
|
||||
else if (PIKA_IS_CHANNEL (pickable))
|
||||
{
|
||||
pika_context_set_image (chooser->priv->context, pika_item_get_image (PIKA_ITEM (pickable)));
|
||||
pika_container_view_select_item (PIKA_CONTAINER_VIEW (chooser->priv->channel_view),
|
||||
PIKA_VIEWABLE (pickable));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_return_if_fail (pickable == NULL);
|
||||
pika_container_view_select_item (PIKA_CONTAINER_VIEW (chooser->priv->image_view), NULL);
|
||||
pika_context_set_image (chooser->priv->context, NULL);
|
||||
}
|
||||
g_signal_connect_object (chooser->priv->image_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
if (chooser->priv->layer_view != NULL)
|
||||
g_signal_connect_object (chooser->priv->layer_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
if (chooser->priv->channel_view != NULL)
|
||||
g_signal_connect_object (chooser->priv->channel_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
if (pickable != chooser->priv->pickable)
|
||||
{
|
||||
g_clear_object (&chooser->priv->pickable);
|
||||
chooser->priv->pickable = (pickable != NULL ? g_object_ref (pickable) : NULL);
|
||||
g_object_notify (G_OBJECT (chooser), "pickable");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_image_changed (PikaContext *context,
|
||||
PikaImage *image,
|
||||
PikaPickableChooser *chooser)
|
||||
{
|
||||
PikaContainer *layers = NULL;
|
||||
PikaContainer *channels = NULL;
|
||||
|
||||
if (image)
|
||||
{
|
||||
gchar *desc;
|
||||
|
||||
layers = pika_image_get_layers (image);
|
||||
channels = pika_image_get_channels (image);
|
||||
|
||||
desc = pika_viewable_get_description (PIKA_VIEWABLE (image), NULL);
|
||||
gtk_label_set_text (GTK_LABEL (chooser->priv->layer_label), desc);
|
||||
g_free (desc);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (chooser->priv->layer_label),
|
||||
_("Select an image in the left pane"));
|
||||
}
|
||||
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->image_view,
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
chooser);
|
||||
if (chooser->priv->layer_view != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->layer_view,
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
chooser);
|
||||
pika_container_view_set_container (PIKA_CONTAINER_VIEW (chooser->priv->layer_view),
|
||||
layers);
|
||||
g_signal_connect_object (chooser->priv->layer_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
if (chooser->priv->channel_view != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (chooser->priv->channel_view,
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
chooser);
|
||||
pika_container_view_set_container (PIKA_CONTAINER_VIEW (chooser->priv->channel_view),
|
||||
channels);
|
||||
g_signal_connect_object (chooser->priv->channel_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
g_signal_connect_object (chooser->priv->image_view, "select-items",
|
||||
G_CALLBACK (pika_pickable_chooser_items_selected),
|
||||
G_OBJECT (chooser), 0);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_item_activate (PikaContainerView *view,
|
||||
PikaPickable *pickable,
|
||||
gpointer unused,
|
||||
PikaPickableChooser *chooser)
|
||||
{
|
||||
g_signal_emit (chooser, signals[ACTIVATE], 0, pickable);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_chooser_items_selected (PikaContainerView *view,
|
||||
GList *items,
|
||||
GList *paths,
|
||||
PikaPickableChooser *chooser)
|
||||
{
|
||||
PikaPickable *pickable = NULL;
|
||||
|
||||
g_return_if_fail (g_list_length (items) <= 1);
|
||||
|
||||
if (items != NULL)
|
||||
pickable = items->data;
|
||||
|
||||
pika_pickable_chooser_set_pickable (chooser, pickable);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* 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
|
||||
*
|
||||
* pikapickablechooser.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* 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_PICKABLE_CHOOSER_H__
|
||||
#define __PIKA_PICKABLE_CHOOSER_H__
|
||||
|
||||
|
||||
#define PIKA_TYPE_PICKABLE_CHOOSER (pika_pickable_chooser_get_type ())
|
||||
#define PIKA_PICKABLE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_PICKABLE_CHOOSER, PikaPickableChooser))
|
||||
#define PIKA_PICKABLE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_PICKABLE_CHOOSER, PikaPickableChooserClass))
|
||||
#define PIKA_IS_PICKABLE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_PICKABLE_CHOOSER))
|
||||
#define PIKA_IS_PICKABLE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_PICKABLE_CHOOSER))
|
||||
#define PIKA_PICKABLE_CHOOSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_PICKABLE_CHOOSER, PikaPickableChooserClass))
|
||||
|
||||
|
||||
typedef struct _PikaPickableChooserPrivate PikaPickableChooserPrivate;
|
||||
typedef struct _PikaPickableChooserClass PikaPickableChooserClass;
|
||||
|
||||
struct _PikaPickableChooser
|
||||
{
|
||||
GtkFrame parent_instance;
|
||||
|
||||
PikaPickableChooserPrivate *priv;
|
||||
};
|
||||
|
||||
struct _PikaPickableChooserClass
|
||||
{
|
||||
GtkFrameClass parent_instance;
|
||||
|
||||
/* Signals. */
|
||||
|
||||
void (* activate) (PikaPickableChooser *view,
|
||||
PikaPickable *pickable);
|
||||
};
|
||||
|
||||
|
||||
GType pika_pickable_chooser_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget * pika_pickable_chooser_new (PikaContext *context,
|
||||
GType pickable_type,
|
||||
gint view_size,
|
||||
gint view_border_width);
|
||||
|
||||
PikaPickable * pika_pickable_chooser_get_pickable (PikaPickableChooser *chooser);
|
||||
void pika_pickable_chooser_set_pickable (PikaPickableChooser *chooser,
|
||||
PikaPickable *pickable);
|
||||
|
||||
|
||||
#endif /* __PIKA_PICKABLE_CHOOSER_H__ */
|
|
@ -0,0 +1,164 @@
|
|||
/* 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
|
||||
*
|
||||
* pikapickableselect.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* 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 "libpikabase/pikabase.h"
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "widgets-types.h"
|
||||
|
||||
#include "gegl/pika-babl-compat.h"
|
||||
|
||||
#include "core/pika.h"
|
||||
#include "core/pikacontext.h"
|
||||
#include "core/pikadrawable.h"
|
||||
#include "core/pikapickable.h"
|
||||
#include "core/pikaparamspecs.h"
|
||||
#include "core/pikatempbuf.h"
|
||||
|
||||
#include "pdb/pikapdb.h"
|
||||
|
||||
#include "pikapickablechooser.h"
|
||||
#include "pikapickableselect.h"
|
||||
#include "pikacontainerbox.h"
|
||||
|
||||
#include "pika-intl.h"
|
||||
|
||||
|
||||
static void pika_pickable_select_constructed (GObject *object);
|
||||
|
||||
static PikaValueArray * pika_pickable_select_run_callback (PikaPdbDialog *dialog,
|
||||
PikaObject *object,
|
||||
gboolean closing,
|
||||
GError **error);
|
||||
static PikaObject * pika_pickable_select_get_object (PikaPdbDialog *dialog);
|
||||
static void pika_pickable_select_set_object (PikaPdbDialog *dialog,
|
||||
PikaObject *object);
|
||||
|
||||
static void pika_pickable_select_activate (PikaPickableSelect *select);
|
||||
static void pika_pickable_select_notify_pickable (PikaPickableSelect *select);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (PikaPickableSelect, pika_pickable_select, PIKA_TYPE_PDB_DIALOG)
|
||||
|
||||
#define parent_class pika_pickable_select_parent_class
|
||||
|
||||
|
||||
static void
|
||||
pika_pickable_select_class_init (PikaPickableSelectClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
PikaPdbDialogClass *pdb_class = PIKA_PDB_DIALOG_CLASS (klass);
|
||||
|
||||
object_class->constructed = pika_pickable_select_constructed;
|
||||
|
||||
pdb_class->run_callback = pika_pickable_select_run_callback;
|
||||
pdb_class->get_object = pika_pickable_select_get_object;
|
||||
pdb_class->set_object = pika_pickable_select_set_object;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_select_init (PikaPickableSelect *select)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_select_constructed (GObject *object)
|
||||
{
|
||||
PikaPdbDialog *dialog = PIKA_PDB_DIALOG (object);
|
||||
PikaPickableSelect *select = PIKA_PICKABLE_SELECT (object);
|
||||
GtkWidget *content_area;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
select->chooser = pika_pickable_chooser_new (dialog->context, dialog->select_type,
|
||||
PIKA_VIEW_SIZE_LARGE, 1);
|
||||
pika_pickable_chooser_set_pickable (PIKA_PICKABLE_CHOOSER (select->chooser),
|
||||
PIKA_PICKABLE (dialog->initial_object));
|
||||
g_signal_connect_swapped (select->chooser, "notify::pickable",
|
||||
G_CALLBACK (pika_pickable_select_notify_pickable),
|
||||
select);
|
||||
g_signal_connect_swapped (select->chooser, "activate",
|
||||
G_CALLBACK (pika_pickable_select_activate),
|
||||
select);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), select->chooser, TRUE, TRUE, 0);
|
||||
gtk_widget_show (select->chooser);
|
||||
}
|
||||
|
||||
static PikaValueArray *
|
||||
pika_pickable_select_run_callback (PikaPdbDialog *dialog,
|
||||
PikaObject *object,
|
||||
gboolean closing,
|
||||
GError **error)
|
||||
{
|
||||
PikaPickable *pickable = PIKA_PICKABLE (object);
|
||||
PikaValueArray *return_vals;
|
||||
|
||||
return_vals =
|
||||
pika_pdb_execute_procedure_by_name (dialog->pdb,
|
||||
dialog->caller_context,
|
||||
NULL, error,
|
||||
dialog->callback_name,
|
||||
PIKA_TYPE_DRAWABLE, pickable,
|
||||
G_TYPE_BOOLEAN, closing,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static PikaObject *
|
||||
pika_pickable_select_get_object (PikaPdbDialog *dialog)
|
||||
{
|
||||
PikaPickableSelect *select = PIKA_PICKABLE_SELECT (dialog);
|
||||
|
||||
return (PikaObject *) pika_pickable_chooser_get_pickable (PIKA_PICKABLE_CHOOSER (select->chooser));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_select_set_object (PikaPdbDialog *dialog,
|
||||
PikaObject *object)
|
||||
{
|
||||
PikaPickableSelect *select = PIKA_PICKABLE_SELECT (dialog);
|
||||
|
||||
pika_pickable_chooser_set_pickable (PIKA_PICKABLE_CHOOSER (select->chooser), PIKA_PICKABLE (object));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_select_activate (PikaPickableSelect *select)
|
||||
{
|
||||
pika_pdb_dialog_run_callback ((PikaPdbDialog **) &select, TRUE);
|
||||
gtk_widget_destroy (GTK_WIDGET (select));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pickable_select_notify_pickable (PikaPickableSelect *select)
|
||||
{
|
||||
pika_pdb_dialog_run_callback ((PikaPdbDialog **) &select, FALSE);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/* 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
|
||||
*
|
||||
* pikapickableselect.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* 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_PICKABLE_SELECT_H__
|
||||
#define __PIKA_PICKABLE_SELECT_H__
|
||||
|
||||
#include "pikapdbdialog.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define PIKA_TYPE_PICKABLE_SELECT (pika_pickable_select_get_type ())
|
||||
#define PIKA_PICKABLE_SELECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_PICKABLE_SELECT, PikaPickableSelect))
|
||||
#define PIKA_PICKABLE_SELECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_PICKABLE_SELECT, PikaPickableSelectClass))
|
||||
#define PIKA_IS_PICKABLE_SELECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_PICKABLE_SELECT))
|
||||
#define PIKA_IS_PICKABLE_SELECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_PICKABLE_SELECT))
|
||||
#define PIKA_PICKABLE_SELECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_PICKABLE_SELECT, PikaPickableSelectClass))
|
||||
|
||||
|
||||
typedef struct _PikaPickableSelectClass PikaPickableSelectClass;
|
||||
|
||||
struct _PikaPickableSelect
|
||||
{
|
||||
PikaPdbDialog parent_instance;
|
||||
|
||||
GtkWidget *chooser;
|
||||
};
|
||||
|
||||
struct _PikaPickableSelectClass
|
||||
{
|
||||
PikaPdbDialogClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType pika_pickable_select_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_PICKABLE_SELECT_H__ */
|
|
@ -0,0 +1,24 @@
|
|||
diff -urN pika-2.10.30-orig/build/windows/pika-plug-ins.rc.in pika-2.10.30/build/windows/pika-plug-ins.rc.in
|
||||
--- pika-2.10.30-orig/build/windows/pika-plug-ins.rc.in 2021-12-20 04:48:33.000000000 +0800
|
||||
+++ pika-2.10.30/build/windows/pika-plug-ins.rc.in 2022-01-05 20:54:00.814712400 +0800
|
||||
@@ -63,5 +63,5 @@
|
||||
END
|
||||
|
||||
#include "winuser.h"
|
||||
-1 ICON QUOTE(TOP_SRCDIR) "/build/windows/plug-ins.ico"
|
||||
-CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST QUOTE(TOP_SRCDIR) "/build/windows/pika.manifest"
|
||||
+1 ICON "./build/windows/plug-ins.ico"
|
||||
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "./build/windows/pika.manifest"
|
||||
diff -urN pika-2.10.30-orig/build/windows/pika.rc.in pika-2.10.30/build/windows/pika.rc.in
|
||||
--- pika-2.10.30-orig/build/windows/pika.rc.in 2021-12-20 04:48:33.000000000 +0800
|
||||
+++ pika-2.10.30/build/windows/pika.rc.in 2022-01-05 20:52:37.741960900 +0800
|
||||
@@ -64,6 +64,6 @@
|
||||
END
|
||||
|
||||
#include "winuser.h"
|
||||
-1 ICON QUOTE(TOP_SRCDIR) "/build/windows/wilber.ico"
|
||||
-2 ICON QUOTE(TOP_SRCDIR) "/build/windows/fileicon.ico"
|
||||
-CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST QUOTE(TOP_SRCDIR) "/build/windows/pika.manifest"
|
||||
+1 ICON "./build/windows/wilber.ico"
|
||||
+2 ICON "./build/windows/fileicon.ico"
|
||||
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "./build/windows/pika.manifest"
|
|
@ -0,0 +1,600 @@
|
|||
diff -bur pika-2.99.12-c/app/meson.build pika-2.99.12/app/meson.build
|
||||
--- pika-2.99.12-c/app/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/app/meson.build 2022-08-26 11:05:18.272156800 -0600
|
||||
@@ -151,9 +151,9 @@
|
||||
console_rc_file = windows.compile_resources(
|
||||
pika_app_console_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(console_rc_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(console_rc_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(console_rc_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(console_rc_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
@@ -169,9 +169,9 @@
|
||||
gui_rc_file = windows.compile_resources(
|
||||
pika_app_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(gui_rc_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(gui_rc_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(gui_rc_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(gui_rc_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/extensions/goat-exercises/meson.build pika-2.99.12/extensions/goat-exercises/meson.build
|
||||
--- pika-2.99.12-c/extensions/goat-exercises/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/extensions/goat-exercises/meson.build 2022-08-26 11:05:21.367326100 -0600
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plug_in_name + '-c.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plug_in_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plug_in_name + '-c.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plug_in_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/common/meson.build pika-2.99.12/plug-ins/common/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/common/meson.build 2022-08-26 10:58:35.055807300 -0600
|
||||
+++ pika-2.99.12/plug-ins/common/meson.build 2022-08-26 11:05:18.323293100 -0600
|
||||
@@ -178,9 +178,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-bmp/meson.build pika-2.99.12/plug-ins/file-bmp/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-bmp/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-bmp/meson.build 2022-08-26 11:05:18.326295200 -0600
|
||||
@@ -10,9 +10,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-dds/meson.build pika-2.99.12/plug-ins/file-dds/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-dds/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-dds/meson.build 2022-08-26 11:05:18.328294700 -0600
|
||||
@@ -14,9 +14,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-exr/meson.build pika-2.99.12/plug-ins/file-exr/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-exr/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-exr/meson.build 2022-08-26 11:05:18.330294400 -0600
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-faxg3/meson.build pika-2.99.12/plug-ins/file-faxg3/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-faxg3/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-faxg3/meson.build 2022-08-26 11:05:18.332294000 -0600
|
||||
@@ -9,9 +9,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
--- pika-2.99.16/plug-ins/file-fits/meson.build.orig 2023-07-06 07:48:46.078752900 +0200
|
||||
+++ pika-2.99.16/plug-ins/file-fits/meson.build 2023-07-06 07:49:41.120861200 +0200
|
||||
@@ -9,9 +9,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-fli/meson.build pika-2.99.12/plug-ins/file-fli/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-fli/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-fli/meson.build 2022-08-26 11:05:18.336295400 -0600
|
||||
@@ -9,9 +9,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-ico/meson.build pika-2.99.12/plug-ins/file-ico/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-ico/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-ico/meson.build 2022-08-26 11:05:18.338293600 -0600
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-jpeg/meson.build pika-2.99.12/plug-ins/file-jpeg/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-jpeg/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-jpeg/meson.build 2022-08-26 11:05:18.340292800 -0600
|
||||
@@ -13,9 +13,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-psd/meson.build pika-2.99.12/plug-ins/file-psd/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-psd/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-psd/meson.build 2022-08-26 11:05:18.342293000 -0600
|
||||
@@ -14,9 +14,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-raw/meson.build pika-2.99.12/plug-ins/file-raw/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-raw/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-raw/meson.build 2022-08-26 11:05:18.344293200 -0600
|
||||
@@ -21,9 +21,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-sgi/meson.build pika-2.99.12/plug-ins/file-sgi/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-sgi/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-sgi/meson.build 2022-08-26 11:05:18.346292800 -0600
|
||||
@@ -9,9 +9,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-tiff/meson.build pika-2.99.12/plug-ins/file-tiff/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-tiff/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-tiff/meson.build 2022-08-26 11:05:18.348293500 -0600
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/file-webp/meson.build pika-2.99.12/plug-ins/file-webp/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/file-webp/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/file-webp/meson.build 2022-08-26 11:05:18.350294300 -0600
|
||||
@@ -13,9 +13,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/flame/meson.build pika-2.99.12/plug-ins/flame/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/flame/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/flame/meson.build 2022-08-26 11:05:18.353294700 -0600
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/fractal-explorer/meson.build pika-2.99.12/plug-ins/fractal-explorer/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/fractal-explorer/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/fractal-explorer/meson.build 2022-08-26 11:05:18.355294200 -0600
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/gfig/meson.build pika-2.99.12/plug-ins/gfig/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/gfig/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/gfig/meson.build 2022-08-26 11:05:18.358466600 -0600
|
||||
@@ -27,9 +27,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/pikaressionist/meson.build pika-2.99.12/plug-ins/pikaressionist/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/pikaressionist/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/pikaressionist/meson.build 2022-08-26 11:05:18.361592500 -0600
|
||||
@@ -29,9 +29,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/gradient-flare/meson.build pika-2.99.12/plug-ins/gradient-flare/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/gradient-flare/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/gradient-flare/meson.build 2022-08-26 11:05:18.365447800 -0600
|
||||
@@ -10,9 +10,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/help/meson.build pika-2.99.12/plug-ins/help/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/help/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/help/meson.build 2022-08-26 11:05:18.367447200 -0600
|
||||
@@ -13,9 +13,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/help-browser/meson.build pika-2.99.12/plug-ins/help-browser/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/help-browser/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/help-browser/meson.build 2022-08-26 11:05:18.369447300 -0600
|
||||
@@ -12,9 +12,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/ifs-compose/meson.build pika-2.99.12/plug-ins/ifs-compose/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/ifs-compose/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/ifs-compose/meson.build 2022-08-26 11:05:18.371447900 -0600
|
||||
@@ -10,9 +10,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/imagemap/meson.build pika-2.99.12/plug-ins/imagemap/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/imagemap/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/imagemap/meson.build 2022-08-26 11:05:18.373620200 -0600
|
||||
@@ -73,9 +73,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/lighting/meson.build pika-2.99.12/plug-ins/lighting/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/lighting/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/lighting/meson.build 2022-08-26 11:05:18.376619900 -0600
|
||||
@@ -17,9 +17,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/map-object/meson.build pika-2.99.12/plug-ins/map-object/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/map-object/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/map-object/meson.build 2022-08-26 11:05:18.378618900 -0600
|
||||
@@ -16,9 +16,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/metadata/meson.build pika-2.99.12/plug-ins/metadata/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/metadata/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/metadata/meson.build 2022-08-26 11:05:18.381620300 -0600
|
||||
@@ -17,9 +17,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
@@ -55,9 +55,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/pagecurl/meson.build pika-2.99.12/plug-ins/pagecurl/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/pagecurl/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/pagecurl/meson.build 2022-08-26 11:05:18.383620200 -0600
|
||||
@@ -41,9 +41,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/print/meson.build pika-2.99.12/plug-ins/print/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/print/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/print/meson.build 2022-08-26 11:05:18.385620400 -0600
|
||||
@@ -17,9 +17,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/script-fu/interpreter/meson.build pika-2.99.12/plug-ins/script-fu/interpreter/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/script-fu/interpreter/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/script-fu/interpreter/meson.build 2022-08-26 11:05:18.388620100 -0600
|
||||
@@ -12,9 +12,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(executable_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(executable_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(executable_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(executable_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/script-fu/meson.build pika-2.99.12/plug-ins/script-fu/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/script-fu/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/script-fu/meson.build 2022-08-26 11:05:18.392620300 -0600
|
||||
@@ -31,9 +31,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(executable_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(executable_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(executable_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(executable_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/script-fu/server/meson.build pika-2.99.12/plug-ins/script-fu/server/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/script-fu/server/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/script-fu/server/meson.build 2022-08-26 11:05:18.394619900 -0600
|
||||
@@ -12,9 +12,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
plugin_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(executable_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(executable_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(executable_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(executable_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/selection-to-path/meson.build pika-2.99.12/plug-ins/selection-to-path/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/selection-to-path/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/selection-to-path/meson.build 2022-08-26 11:05:18.396618000 -0600
|
||||
@@ -16,9 +16,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
diff -bur pika-2.99.12-c/plug-ins/twain/meson.build pika-2.99.12/plug-ins/twain/meson.build
|
||||
--- pika-2.99.12-c/plug-ins/twain/meson.build 2022-08-21 13:21:38.000000000 -0600
|
||||
+++ pika-2.99.12/plug-ins/twain/meson.build 2022-08-26 11:05:18.398619200 -0600
|
||||
@@ -14,9 +14,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
||||
--- pika-2.99.14/plug-ins/file-icns/meson.build.orig 2022-11-14 00:04:38.000000000 +0100
|
||||
+++ pika-2.99.14/plug-ins/file-icns/meson.build 2022-11-19 21:03:14.665912600 +0100
|
||||
@@ -11,9 +11,9 @@
|
||||
plugin_sources += windows.compile_resources(
|
||||
pika_plugins_rc,
|
||||
args: [
|
||||
- '--define', 'ORIGINALFILENAME_STR="@0@"'.format(plugin_name+'.exe'),
|
||||
- '--define', 'INTERNALNAME_STR="@0@"' .format(plugin_name),
|
||||
- '--define', 'TOP_SRCDIR="@0@"' .format(meson.project_source_root()),
|
||||
+ '--define', 'ORIGINALFILENAME_STR=@0@'.format(plugin_name+'.exe'),
|
||||
+ '--define', 'INTERNALNAME_STR=@0@' .format(plugin_name),
|
||||
+ '--define', 'TOP_SRCDIR=@0@' .format(meson.project_source_root()),
|
||||
],
|
||||
include_directories: [
|
||||
rootInclude, appInclude,
|
|
@ -0,0 +1,312 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikabrush.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikabrush.h"
|
||||
|
||||
struct _PikaBrush
|
||||
{
|
||||
PikaResource parent_instance;
|
||||
|
||||
/* Native size buffers of the brush contents. */
|
||||
GeglBuffer *buffer;
|
||||
GeglBuffer *mask;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (PikaBrush, pika_brush, PIKA_TYPE_RESOURCE);
|
||||
|
||||
static void pika_brush_finalize (GObject *object);
|
||||
static void pika_brush_get_data (PikaBrush *brush);
|
||||
static GeglBuffer * pika_brush_scale (GeglBuffer *buffer,
|
||||
gint max_width,
|
||||
gint max_height);
|
||||
static const Babl * pika_brush_data_get_format (gint bpp,
|
||||
gboolean with_alpha);
|
||||
|
||||
|
||||
static void pika_brush_class_init (PikaBrushClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = pika_brush_finalize;
|
||||
}
|
||||
|
||||
static void pika_brush_init (PikaBrush *brush)
|
||||
{
|
||||
brush->buffer = NULL;
|
||||
brush->mask = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_brush_finalize (GObject *object)
|
||||
{
|
||||
PikaBrush *brush = PIKA_BRUSH (object);
|
||||
|
||||
g_clear_object (&brush->buffer);
|
||||
g_clear_object (&brush->mask);
|
||||
|
||||
G_OBJECT_CLASS (pika_brush_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pika_brush_get_buffer:
|
||||
* @brush: a [class@Brush].
|
||||
* @max_width: a maximum width for the returned buffer.
|
||||
* @max_height: a maximum height for the returned buffer.
|
||||
* @format: an optional Babl format.
|
||||
*
|
||||
* Gets pixel data of the brush within the bounding box specified by @max_width
|
||||
* and @max_height. The data will be scaled down so that it fits within this
|
||||
* size without changing its ratio. If the brush is smaller than this size to
|
||||
* begin with, it will not be scaled up.
|
||||
*
|
||||
* If @max_width or @max_height are %NULL, the buffer is returned in the brush's
|
||||
* native size.
|
||||
*
|
||||
* When the brush is parametric or a raster mask, only the mask (as returned by
|
||||
* [method@Gimp.Brush.get_mask]) will be set. The returned buffer will be NULL.
|
||||
*
|
||||
* Make sure you called [func@Gegl.init] before calling any function using
|
||||
* `GEGL`.
|
||||
*
|
||||
* Returns: (transfer full): a [class@Gegl.Buffer] of %NULL if the brush is parametric
|
||||
* or mask only.
|
||||
*/
|
||||
GeglBuffer *
|
||||
pika_brush_get_buffer (PikaBrush *brush,
|
||||
gint max_width,
|
||||
gint max_height,
|
||||
const Babl *format)
|
||||
{
|
||||
pika_brush_get_data (brush);
|
||||
|
||||
if (brush->buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
if (max_width == 0 || max_height == 0 ||
|
||||
(gegl_buffer_get_width (brush->buffer) <= max_width &&
|
||||
gegl_buffer_get_height (brush->buffer) <= max_height))
|
||||
return gegl_buffer_dup (brush->buffer);
|
||||
|
||||
return pika_brush_scale (brush->buffer, max_width, max_height);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_brush_get_mask:
|
||||
* @brush: a [class@Brush].
|
||||
* @max_width: a maximum width for the returned buffer.
|
||||
* @max_height: a maximum height for the returned buffer.
|
||||
* @format: an optional Babl format.
|
||||
*
|
||||
* Gets mask data of the brush within the bounding box specified by @max_width
|
||||
* and @max_height. The data will be scaled down so that it fits within this
|
||||
* size without changing its ratio. If the brush is smaller than this size to
|
||||
* begin with, it will not be scaled up.
|
||||
*
|
||||
* If @max_width or @max_height are %NULL, the buffer is returned in the brush's
|
||||
* native size.
|
||||
*
|
||||
* Make sure you called [func@Gegl.init] before calling any function using
|
||||
* `GEGL`.
|
||||
*
|
||||
* Returns: (transfer full): a [class@Gegl.Buffer] representing the @brush mask.
|
||||
*/
|
||||
GeglBuffer *
|
||||
pika_brush_get_mask (PikaBrush *brush,
|
||||
gint max_width,
|
||||
gint max_height,
|
||||
const Babl *format)
|
||||
{
|
||||
pika_brush_get_data (brush);
|
||||
|
||||
g_return_val_if_fail (brush->mask != NULL, NULL);
|
||||
|
||||
if (max_width == 0 || max_height == 0 ||
|
||||
(gegl_buffer_get_width (brush->mask) <= max_width &&
|
||||
gegl_buffer_get_height (brush->mask) <= max_height))
|
||||
return gegl_buffer_dup (brush->mask);
|
||||
|
||||
return pika_brush_scale (brush->mask, max_width, max_height);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_brush_get_data (PikaBrush *brush)
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
gint mask_bpp;
|
||||
GBytes *mask_bytes;
|
||||
gint color_bpp;
|
||||
GBytes *color_bytes;
|
||||
const guchar *mask;
|
||||
gsize mask_size;
|
||||
const guchar *color;
|
||||
gsize color_size;
|
||||
|
||||
/* We check the mask because the buffer might be NULL.
|
||||
*
|
||||
* This check assumes that the brush contents doesn't change, which is not a
|
||||
* perfect assumption. We could maybe add a PDB call which would return
|
||||
* the new brush data only if it changed since last call (which can be
|
||||
* verified with some kind of internal runtime version to pass from one call
|
||||
* to another). TODO
|
||||
*/
|
||||
if (brush->mask != NULL)
|
||||
return;
|
||||
|
||||
g_clear_object (&brush->buffer);
|
||||
g_clear_object (&brush->mask);
|
||||
|
||||
_pika_brush_get_pixels (brush, &width, &height,
|
||||
&mask_bpp, &mask_bytes,
|
||||
&color_bpp, &color_bytes);
|
||||
|
||||
mask = g_bytes_unref_to_data (mask_bytes, &mask_size);
|
||||
color = g_bytes_unref_to_data (color_bytes, &color_size);
|
||||
|
||||
brush->mask = gegl_buffer_linear_new_from_data ((const gpointer) mask,
|
||||
pika_brush_data_get_format (mask_bpp, FALSE),
|
||||
GEGL_RECTANGLE (0, 0, width, height),
|
||||
0, g_free, NULL);
|
||||
if (color_bpp > 0)
|
||||
{
|
||||
GeglBufferIterator *gi;
|
||||
GeglBuffer *buffer;
|
||||
|
||||
buffer = gegl_buffer_linear_new_from_data ((const gpointer) color,
|
||||
pika_brush_data_get_format (color_bpp, FALSE),
|
||||
GEGL_RECTANGLE (0, 0, width, height),
|
||||
0, g_free, NULL);
|
||||
brush->buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, width, height),
|
||||
pika_brush_data_get_format (color_bpp, TRUE));
|
||||
|
||||
gi = gegl_buffer_iterator_new (brush->buffer, NULL, 0, NULL,
|
||||
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE, 3);
|
||||
gegl_buffer_iterator_add (gi, buffer, GEGL_RECTANGLE (0, 0, width, height),
|
||||
0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
|
||||
gegl_buffer_iterator_add (gi, brush->mask, GEGL_RECTANGLE (0, 0, width, height),
|
||||
0, NULL, GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
|
||||
while (gegl_buffer_iterator_next (gi))
|
||||
{
|
||||
guint8 *out = gi->items[0].data;
|
||||
guint8 *color = gi->items[1].data;
|
||||
guint8 *alpha = gi->items[2].data;
|
||||
|
||||
for (gint i = 0; i < gi->length; i++)
|
||||
{
|
||||
gint c;
|
||||
|
||||
for (c = 0; c < color_bpp; c++)
|
||||
out[c] = color[c];
|
||||
|
||||
out[c] = alpha[0];
|
||||
|
||||
out += color_bpp + 1;
|
||||
color += color_bpp;
|
||||
alpha += 1;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static GeglBuffer *
|
||||
pika_brush_scale (GeglBuffer *buffer,
|
||||
gint max_width,
|
||||
gint max_height)
|
||||
{
|
||||
GeglBuffer *scaled = NULL;
|
||||
GeglNode *graph;
|
||||
GeglNode *source;
|
||||
GeglNode *op;
|
||||
GeglNode *sink;
|
||||
gdouble width;
|
||||
gdouble height;
|
||||
gdouble scale;
|
||||
|
||||
height = (gdouble) max_height;
|
||||
width = (gdouble) gegl_buffer_get_width (buffer) / gegl_buffer_get_height (buffer) * height;
|
||||
if (width > (gdouble) max_width)
|
||||
{
|
||||
width = (gdouble) max_width;
|
||||
height = (gdouble) gegl_buffer_get_height (buffer) / gegl_buffer_get_width (buffer) * width;
|
||||
}
|
||||
scale = width / gegl_buffer_get_width (buffer);
|
||||
|
||||
graph = gegl_node_new ();
|
||||
source = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", buffer,
|
||||
NULL);
|
||||
op = gegl_node_new_child (graph,
|
||||
"operation", "gegl:scale-ratio",
|
||||
"origin-x", 0.0,
|
||||
"origin-y", 0.0,
|
||||
"sampler", PIKA_INTERPOLATION_LINEAR,
|
||||
"abyss-policy", GEGL_ABYSS_CLAMP,
|
||||
"x", scale,
|
||||
"y", scale,
|
||||
NULL);
|
||||
sink = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-sink",
|
||||
"buffer", &scaled,
|
||||
"format", gegl_buffer_get_format (buffer),
|
||||
NULL);
|
||||
gegl_node_link_many (source, op, sink, NULL);
|
||||
gegl_node_process (sink);
|
||||
|
||||
g_object_unref (graph);
|
||||
|
||||
return scaled;
|
||||
}
|
||||
|
||||
static const Babl *
|
||||
pika_brush_data_get_format (gint bpp,
|
||||
gboolean with_alpha)
|
||||
{
|
||||
/* It's an ugly way to determine the proper format but pika_brush_get_pixels()
|
||||
* doesn't give more info.
|
||||
*/
|
||||
switch (bpp)
|
||||
{
|
||||
case 1:
|
||||
if (! with_alpha)
|
||||
return babl_format ("Y' u8");
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
return babl_format ("Y'A u8");
|
||||
case 3:
|
||||
if (! with_alpha)
|
||||
return babl_format ("R'G'B' u8");
|
||||
/* fallthrough */
|
||||
case 4:
|
||||
return babl_format ("R'G'B'A u8");
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikabrush.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pika.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_BRUSH_H__
|
||||
#define __PIKA_BRUSH_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#include <libpika/pikaresource.h>
|
||||
|
||||
|
||||
#define PIKA_TYPE_BRUSH (pika_brush_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaBrush, pika_brush, PIKA, BRUSH, PikaResource)
|
||||
|
||||
|
||||
GeglBuffer * pika_brush_get_buffer (PikaBrush *brush,
|
||||
gint max_width,
|
||||
gint max_height,
|
||||
const Babl *format) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GeglBuffer * pika_brush_get_mask (PikaBrush *brush,
|
||||
gint max_width,
|
||||
gint max_height,
|
||||
const Babl *format) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_BRUSH_H__ */
|
|
@ -0,0 +1,456 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikabrushchooser.c
|
||||
* Copyright (C) 1998 Andy Thomas
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikabrushchooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikabrushchooser
|
||||
* @title: PikaBrushChooser
|
||||
* @short_description: A button which pops up a brush selection dialog.
|
||||
*
|
||||
* A button which pops up a brush selection dialog.
|
||||
*
|
||||
* Note that this widget draws itself using `GEGL` code. You **must** call
|
||||
* [func@Gegl.init] first to be able to use this chooser.
|
||||
**/
|
||||
|
||||
#define CELL_SIZE 40
|
||||
|
||||
struct _PikaBrushChooser
|
||||
{
|
||||
PikaResourceChooser parent_instance;
|
||||
|
||||
GtkWidget *preview;
|
||||
GtkWidget *popup;
|
||||
|
||||
PikaBrush *brush;
|
||||
gint width;
|
||||
gint height;
|
||||
GeglBuffer *buffer;
|
||||
GeglBuffer *mask;
|
||||
};
|
||||
|
||||
|
||||
static void pika_brush_chooser_finalize (GObject *object);
|
||||
|
||||
static gboolean pika_brush_select_on_preview_events (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
PikaBrushChooser *button);
|
||||
|
||||
static void pika_brush_select_preview_draw (PikaBrushChooser *chooser,
|
||||
PikaPreviewArea *area);
|
||||
|
||||
static void pika_brush_chooser_draw (PikaBrushChooser *self);
|
||||
static void pika_brush_chooser_get_brush_bitmap (PikaBrushChooser *self,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
/* Popup methods. */
|
||||
static void pika_brush_chooser_open_popup (PikaBrushChooser *button,
|
||||
gint x,
|
||||
gint y);
|
||||
static void pika_brush_chooser_close_popup (PikaBrushChooser *button);
|
||||
|
||||
|
||||
static const GtkTargetEntry drag_target = { "application/x-pika-brush-name", 0, 0 };
|
||||
|
||||
G_DEFINE_FINAL_TYPE (PikaBrushChooser, pika_brush_chooser, PIKA_TYPE_RESOURCE_CHOOSER)
|
||||
|
||||
|
||||
static void
|
||||
pika_brush_chooser_class_init (PikaBrushChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
PikaResourceChooserClass *res_class = PIKA_RESOURCE_CHOOSER_CLASS (klass);
|
||||
|
||||
res_class->draw_interior = (void (*)(PikaResourceChooser *)) pika_brush_chooser_draw;
|
||||
res_class->resource_type = PIKA_TYPE_BRUSH;
|
||||
|
||||
object_class->finalize = pika_brush_chooser_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_brush_chooser_init (PikaBrushChooser *chooser)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
gint scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (chooser));
|
||||
|
||||
chooser->brush = NULL;
|
||||
chooser->buffer = NULL;
|
||||
chooser->mask = NULL;
|
||||
|
||||
widget = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (chooser), widget, FALSE, FALSE, 0);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
chooser->preview = pika_preview_area_new ();
|
||||
gtk_widget_add_events (chooser->preview,
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
|
||||
gtk_widget_set_size_request (chooser->preview, scale_factor * CELL_SIZE, scale_factor * CELL_SIZE);
|
||||
gtk_container_add (GTK_CONTAINER (widget), chooser->preview);
|
||||
gtk_widget_show (chooser->preview);
|
||||
|
||||
g_signal_connect_swapped (chooser->preview, "size-allocate",
|
||||
G_CALLBACK (pika_brush_chooser_draw),
|
||||
chooser);
|
||||
|
||||
g_signal_connect (chooser->preview, "event",
|
||||
G_CALLBACK (pika_brush_select_on_preview_events),
|
||||
chooser);
|
||||
|
||||
widget = gtk_button_new_with_mnemonic (_("_Browse..."));
|
||||
gtk_box_pack_start (GTK_BOX (chooser), widget, FALSE, FALSE, 0);
|
||||
|
||||
pika_resource_chooser_set_drag_target (PIKA_RESOURCE_CHOOSER (chooser),
|
||||
chooser->preview,
|
||||
&drag_target);
|
||||
|
||||
pika_resource_chooser_set_clickable (PIKA_RESOURCE_CHOOSER (chooser),
|
||||
widget);
|
||||
gtk_widget_show (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_brush_chooser_finalize (GObject *object)
|
||||
{
|
||||
PikaBrushChooser *chooser = PIKA_BRUSH_CHOOSER (object);
|
||||
|
||||
g_clear_object (&chooser->buffer);
|
||||
g_clear_object (&chooser->mask);
|
||||
|
||||
G_OBJECT_CLASS (pika_brush_chooser_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_brush_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @resource: (nullable): Initial brush.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a brush.
|
||||
* You can put this widget in a plug-in dialog.
|
||||
*
|
||||
* When brush is NULL, initial choice is from context.
|
||||
*
|
||||
* Returns: A #GtkWidget that you can use in your UI.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_brush_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource)
|
||||
{
|
||||
GtkWidget *self;
|
||||
|
||||
if (resource == NULL)
|
||||
resource = PIKA_RESOURCE (pika_context_get_brush ());
|
||||
|
||||
if (title)
|
||||
self = g_object_new (PIKA_TYPE_BRUSH_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
else
|
||||
self = g_object_new (PIKA_TYPE_BRUSH_CHOOSER,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
pika_brush_chooser_draw (PikaBrushChooser *chooser)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_get_allocation (chooser->preview, &allocation);
|
||||
|
||||
pika_brush_chooser_get_brush_bitmap (chooser, allocation.width, allocation.height);
|
||||
pika_brush_select_preview_draw (chooser, PIKA_PREVIEW_AREA (chooser->preview));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_brush_chooser_get_brush_bitmap (PikaBrushChooser *chooser,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
PikaBrush *brush;
|
||||
|
||||
g_object_get (chooser, "resource", &brush, NULL);
|
||||
|
||||
if (chooser->brush == brush &&
|
||||
chooser->width == width &&
|
||||
chooser->height == height)
|
||||
{
|
||||
/* Let's assume brush contents is not changing in a single run. */
|
||||
g_object_unref (brush);
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_object (&chooser->buffer);
|
||||
g_clear_object (&chooser->mask);
|
||||
chooser->width = chooser->height = 0;
|
||||
|
||||
chooser->brush = brush;
|
||||
chooser->buffer = pika_brush_get_buffer (brush, width, height, NULL);
|
||||
|
||||
if (chooser->buffer)
|
||||
{
|
||||
GeglColor *white_color = gegl_color_new ("rgb(1.0,1.0,1.0)");
|
||||
GeglNode *graph;
|
||||
GeglNode *white;
|
||||
GeglNode *source;
|
||||
GeglNode *op;
|
||||
|
||||
chooser->width = gegl_buffer_get_width (chooser->buffer);
|
||||
chooser->height = gegl_buffer_get_height (chooser->buffer);
|
||||
|
||||
graph = gegl_node_new ();
|
||||
white = gegl_node_new_child (graph,
|
||||
"operation", "gegl:rectangle",
|
||||
"x", 0.0,
|
||||
"y", 0.0,
|
||||
"width", (gdouble) gegl_buffer_get_width (chooser->buffer),
|
||||
"height", (gdouble) gegl_buffer_get_height (chooser->buffer),
|
||||
"color", white_color,
|
||||
NULL);
|
||||
source = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", chooser->buffer,
|
||||
NULL);
|
||||
op = gegl_node_new_child (graph,
|
||||
"operation", "svg:src-over",
|
||||
NULL);
|
||||
gegl_node_link_many (white, op, NULL);
|
||||
gegl_node_connect (source, "output", op, "aux");
|
||||
gegl_node_blit_buffer (op, chooser->buffer, NULL, 0, GEGL_ABYSS_NONE);
|
||||
|
||||
g_object_unref (graph);
|
||||
g_object_unref (white_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
GeglBufferIterator *iter;
|
||||
|
||||
chooser->mask = pika_brush_get_mask (brush, width, height, NULL);
|
||||
chooser->width = gegl_buffer_get_width (chooser->mask);
|
||||
chooser->height = gegl_buffer_get_height (chooser->mask);
|
||||
|
||||
/* More common to display mask brushes as black on white. */
|
||||
iter = gegl_buffer_iterator_new (chooser->mask, NULL, 0,
|
||||
babl_format ("Y' u8"),
|
||||
GEGL_ACCESS_READWRITE,
|
||||
GEGL_ABYSS_NONE, 1);
|
||||
|
||||
while (gegl_buffer_iterator_next (iter))
|
||||
{
|
||||
guint8 *data = iter->items[0].data;
|
||||
|
||||
for (gint i = 0; i < iter->length; i++)
|
||||
{
|
||||
*data = 255 - *data;
|
||||
data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (brush);
|
||||
}
|
||||
|
||||
/* On mouse events in self's preview, popup a zoom view of entire brush */
|
||||
static gboolean
|
||||
pika_brush_select_on_preview_events (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
PikaBrushChooser *self)
|
||||
{
|
||||
GdkEventButton *bevent;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_BUTTON_PRESS:
|
||||
bevent = (GdkEventButton *) event;
|
||||
|
||||
if (bevent->button == 1)
|
||||
{
|
||||
gtk_grab_add (widget);
|
||||
pika_brush_chooser_open_popup (self,
|
||||
bevent->x, bevent->y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
bevent = (GdkEventButton *) event;
|
||||
|
||||
if (bevent->button == 1)
|
||||
{
|
||||
gtk_grab_remove (widget);
|
||||
pika_brush_chooser_close_popup (self);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Draw a PikaPreviewArea with a given bitmap. */
|
||||
static void
|
||||
pika_brush_select_preview_draw (PikaBrushChooser *chooser,
|
||||
PikaPreviewArea *preview)
|
||||
{
|
||||
PikaPreviewArea *area = PIKA_PREVIEW_AREA (preview);
|
||||
GeglBuffer *src_buffer;
|
||||
const Babl *format;
|
||||
guchar *src;
|
||||
PikaImageType type;
|
||||
gint rowstride;
|
||||
GtkAllocation allocation;
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
|
||||
gtk_widget_get_allocation (GTK_WIDGET (preview), &allocation);
|
||||
|
||||
/* Fill with white. */
|
||||
if (chooser->width < allocation.width ||
|
||||
chooser->height < allocation.height)
|
||||
{
|
||||
pika_preview_area_fill (area,
|
||||
0, 0,
|
||||
allocation.width,
|
||||
allocation.height,
|
||||
0xFF, 0xFF, 0xFF);
|
||||
|
||||
x = ((allocation.width - chooser->width) / 2);
|
||||
y = ((allocation.height - chooser->height) / 2);
|
||||
}
|
||||
|
||||
/* Draw the brush. */
|
||||
if (chooser->buffer)
|
||||
{
|
||||
src_buffer = chooser->buffer;
|
||||
format = gegl_buffer_get_format (src_buffer);
|
||||
rowstride = chooser->width * babl_format_get_bytes_per_pixel (format);
|
||||
if (babl_format_has_alpha (format))
|
||||
type = PIKA_RGBA_IMAGE;
|
||||
else
|
||||
type = PIKA_RGB_IMAGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_buffer = chooser->mask;
|
||||
format = babl_format ("Y' u8");
|
||||
rowstride = chooser->width;
|
||||
type = PIKA_GRAY_IMAGE;
|
||||
}
|
||||
|
||||
src = g_try_malloc (sizeof (guchar) * rowstride * chooser->height);
|
||||
|
||||
gegl_buffer_get (src_buffer, NULL, 1.0, format, src, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
pika_preview_area_draw (area, x, y, chooser->width, chooser->height, type, src, rowstride);
|
||||
|
||||
g_free (src);
|
||||
}
|
||||
|
||||
/* popup methods. */
|
||||
|
||||
static void
|
||||
pika_brush_chooser_open_popup (PikaBrushChooser *chooser,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *preview;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
gint x_org;
|
||||
gint y_org;
|
||||
|
||||
if (chooser->popup)
|
||||
pika_brush_chooser_close_popup (chooser);
|
||||
|
||||
if (chooser->width <= CELL_SIZE && chooser->height <= CELL_SIZE)
|
||||
return;
|
||||
|
||||
chooser->popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (chooser->popup), GDK_WINDOW_TYPE_HINT_DND);
|
||||
gtk_window_set_screen (GTK_WINDOW (chooser->popup),
|
||||
gtk_widget_get_screen (GTK_WIDGET (chooser)));
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add (GTK_CONTAINER (chooser->popup), frame);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
preview = pika_preview_area_new ();
|
||||
gtk_widget_set_size_request (preview, chooser->width, chooser->height);
|
||||
gtk_container_add (GTK_CONTAINER (frame), preview);
|
||||
gtk_widget_show (preview);
|
||||
|
||||
/* decide where to put the popup: near the preview i.e. at mousedown coords */
|
||||
gdk_window_get_origin (gtk_widget_get_window (chooser->preview),
|
||||
&x_org, &y_org);
|
||||
|
||||
monitor = pika_widget_get_monitor (GTK_WIDGET (chooser));
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
x = x_org + x - (chooser->width / 2);
|
||||
y = y_org + y - (chooser->height / 2);
|
||||
|
||||
x = CLAMP (x, workarea.x, workarea.x + workarea.width - chooser->width);
|
||||
y = CLAMP (y, workarea.y, workarea.y + workarea.height - chooser->height);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (chooser->popup), x, y);
|
||||
|
||||
gtk_widget_show (chooser->popup);
|
||||
|
||||
/* Draw popup now. Usual events do not cause a draw. */
|
||||
pika_brush_select_preview_draw (chooser, PIKA_PREVIEW_AREA (preview));
|
||||
gdk_window_set_transient_for (gtk_widget_get_window (chooser->popup),
|
||||
gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (chooser))));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_brush_chooser_close_popup (PikaBrushChooser *self)
|
||||
{
|
||||
g_clear_pointer (&self->popup, gtk_widget_destroy);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikabrushchooser.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_BRUSH_CHOOSER_H__
|
||||
#define __PIKA_BRUSH_CHOOSER_H__
|
||||
|
||||
#include <libpika/pikaresourcechooser.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_BRUSH_CHOOSER (pika_brush_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaBrushChooser, pika_brush_chooser, PIKA, BRUSH_CHOOSER, PikaResourceChooser)
|
||||
|
||||
|
||||
GtkWidget * pika_brush_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_BRUSH_CHOOSER_H__ */
|
|
@ -0,0 +1,615 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikadrawablechooser.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikadrawablechooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikadrawablechooser
|
||||
* @title: PikaDrawableChooser
|
||||
* @short_description: A widget allowing to select a drawable.
|
||||
*
|
||||
* The chooser contains an optional label and a button which queries the core
|
||||
* process to pop up a drawable selection dialog.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
|
||||
#define CELL_SIZE 40
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_LABEL,
|
||||
PROP_DRAWABLE,
|
||||
PROP_DRAWABLE_TYPE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
struct _PikaDrawableChooser
|
||||
{
|
||||
GtkBox parent_instance;
|
||||
|
||||
GType drawable_type;
|
||||
PikaDrawable *drawable;
|
||||
gchar *title;
|
||||
gchar *label;
|
||||
gchar *callback;
|
||||
|
||||
GBytes *thumbnail;
|
||||
PikaDrawable *thumbnail_drawable;
|
||||
gint width;
|
||||
gint height;
|
||||
gint bpp;
|
||||
|
||||
GtkWidget *label_widget;
|
||||
GtkWidget *preview_frame;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *preview_title;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void pika_drawable_chooser_constructed (GObject *object);
|
||||
static void pika_drawable_chooser_dispose (GObject *object);
|
||||
static void pika_drawable_chooser_finalize (GObject *object);
|
||||
|
||||
static void pika_drawable_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void pika_drawable_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void pika_drawable_chooser_clicked (PikaDrawableChooser *chooser);
|
||||
|
||||
static PikaValueArray * pika_temp_callback_run (PikaProcedure *procedure,
|
||||
PikaProcedureConfig *config,
|
||||
PikaDrawableChooser *chooser);
|
||||
static gboolean pika_drawable_select_remove_after_run (const gchar *procedure_name);
|
||||
|
||||
static void pika_drawable_chooser_draw (PikaDrawableChooser *chooser);
|
||||
static void pika_drawable_chooser_get_thumbnail (PikaDrawableChooser *chooser,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
|
||||
static GParamSpec *drawable_button_props[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_FINAL_TYPE (PikaDrawableChooser, pika_drawable_chooser, GTK_TYPE_BOX)
|
||||
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_class_init (PikaDrawableChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = pika_drawable_chooser_constructed;
|
||||
object_class->dispose = pika_drawable_chooser_dispose;
|
||||
object_class->finalize = pika_drawable_chooser_finalize;
|
||||
object_class->set_property = pika_drawable_chooser_set_property;
|
||||
object_class->get_property = pika_drawable_chooser_get_property;
|
||||
|
||||
/**
|
||||
* PikaDrawableChooser:title:
|
||||
*
|
||||
* The title to be used for the drawable selection popup dialog.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
drawable_button_props[PROP_TITLE] =
|
||||
g_param_spec_string ("title",
|
||||
"Title",
|
||||
"The title to be used for the drawable selection popup dialog",
|
||||
"Drawable Selection",
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* PikaDrawableChooser:label:
|
||||
*
|
||||
* Label text with mnemonic.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
drawable_button_props[PROP_LABEL] =
|
||||
g_param_spec_string ("label",
|
||||
"Label",
|
||||
"The label to be used next to the button",
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* PikaDrawableChooser:drawable:
|
||||
*
|
||||
* The currently selected drawable.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
drawable_button_props[PROP_DRAWABLE] =
|
||||
pika_param_spec_drawable ("drawable",
|
||||
"Drawable",
|
||||
"The currently selected drawable",
|
||||
TRUE,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* PikaDrawableChooser:drawable-type:
|
||||
*
|
||||
* Allowed drawable types, which must be either PIKA_TYPE_DRAWABLE or a
|
||||
* subtype.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
drawable_button_props[PROP_DRAWABLE_TYPE] =
|
||||
g_param_spec_gtype ("drawable-type",
|
||||
"Allowed drawable Type",
|
||||
"The GType of the drawable property",
|
||||
PIKA_TYPE_DRAWABLE,
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
PIKA_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class,
|
||||
N_PROPS, drawable_button_props);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_init (PikaDrawableChooser *chooser)
|
||||
{
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (chooser),
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_box_set_spacing (GTK_BOX (chooser), 6);
|
||||
|
||||
chooser->thumbnail_drawable = NULL;
|
||||
chooser->thumbnail = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_constructed (GObject *object)
|
||||
{
|
||||
PikaDrawableChooser *chooser = PIKA_DRAWABLE_CHOOSER (object);
|
||||
GtkWidget *button;
|
||||
GtkWidget *box;
|
||||
gint scale_factor;
|
||||
|
||||
scale_factor = gtk_widget_get_scale_factor (GTK_WIDGET (chooser));
|
||||
|
||||
chooser->label_widget = gtk_label_new (NULL);
|
||||
gtk_box_pack_start (GTK_BOX (chooser), chooser->label_widget, FALSE, FALSE, 0);
|
||||
gtk_label_set_text_with_mnemonic (GTK_LABEL (chooser->label_widget), chooser->label);
|
||||
gtk_widget_show (GTK_WIDGET (chooser->label_widget));
|
||||
|
||||
button = gtk_button_new ();
|
||||
gtk_box_pack_start (GTK_BOX (chooser), button, FALSE, FALSE, 0);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (chooser->label_widget), button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
|
||||
gtk_container_add (GTK_CONTAINER (button), box);
|
||||
gtk_widget_show (box);
|
||||
|
||||
chooser->preview_frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (chooser->preview_frame), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (box), chooser->preview_frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (chooser->preview_frame);
|
||||
|
||||
chooser->preview = pika_preview_area_new ();
|
||||
gtk_widget_set_size_request (chooser->preview, scale_factor * CELL_SIZE, scale_factor * CELL_SIZE);
|
||||
gtk_container_add (GTK_CONTAINER (chooser->preview_frame), chooser->preview);
|
||||
gtk_widget_show (chooser->preview);
|
||||
|
||||
chooser->preview_title = gtk_label_new (_("Browse..."));
|
||||
gtk_box_pack_start (GTK_BOX (box), chooser->preview_title, FALSE, FALSE, 0);
|
||||
gtk_widget_show (chooser->preview_title);
|
||||
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (pika_drawable_chooser_clicked),
|
||||
chooser);
|
||||
|
||||
G_OBJECT_CLASS (pika_drawable_chooser_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_dispose (GObject *object)
|
||||
{
|
||||
PikaDrawableChooser *chooser = PIKA_DRAWABLE_CHOOSER (object);
|
||||
|
||||
if (chooser->callback)
|
||||
{
|
||||
pika_drawables_close_popup (chooser->callback);
|
||||
|
||||
pika_plug_in_remove_temp_procedure (pika_get_plug_in (), chooser->callback);
|
||||
g_clear_pointer (&chooser->callback, g_free);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (pika_drawable_chooser_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_finalize (GObject *object)
|
||||
{
|
||||
PikaDrawableChooser *chooser = PIKA_DRAWABLE_CHOOSER (object);
|
||||
|
||||
g_clear_pointer (&chooser->title, g_free);
|
||||
g_clear_pointer (&chooser->label, g_free);
|
||||
g_clear_pointer (&chooser->thumbnail, g_bytes_unref);
|
||||
|
||||
G_OBJECT_CLASS (pika_drawable_chooser_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *gvalue,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaDrawableChooser *chooser = PIKA_DRAWABLE_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
chooser->title = g_value_dup_string (gvalue);
|
||||
break;
|
||||
|
||||
case PROP_LABEL:
|
||||
chooser->label = g_value_dup_string (gvalue);
|
||||
break;
|
||||
|
||||
case PROP_DRAWABLE:
|
||||
g_return_if_fail (g_value_get_object (gvalue) == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (g_value_get_object (gvalue)),
|
||||
chooser->drawable_type));
|
||||
pika_drawable_chooser_set_drawable (chooser, g_value_get_object (gvalue));
|
||||
break;
|
||||
|
||||
case PROP_DRAWABLE_TYPE:
|
||||
chooser->drawable_type = g_value_get_gtype (gvalue);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaDrawableChooser *chooser = PIKA_DRAWABLE_CHOOSER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, chooser->title);
|
||||
break;
|
||||
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, chooser->label);
|
||||
break;
|
||||
|
||||
case PROP_DRAWABLE:
|
||||
g_value_set_object (value, chooser->drawable);
|
||||
break;
|
||||
|
||||
case PROP_DRAWABLE_TYPE:
|
||||
g_value_set_gtype (value, chooser->drawable_type);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_drawable_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @drawable_type: the acceptable subtype of choosable drawables.
|
||||
* @drawable: (nullable): Initial drawable.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a drawable which must be of
|
||||
* type @drawable_type. @drawable_type of values %G_TYPE_NONE and
|
||||
* %PIKA_TYPE_DRAWABLE are equivalent. Otherwise it must be a subtype of
|
||||
* %PIKA_TYPE_DRAWABLE.
|
||||
*
|
||||
* When @drawable is %NULL, initial choice is from context.
|
||||
*
|
||||
* Returns: A [class@GimpUi.DrawableChooser.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_drawable_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
GType drawable_type,
|
||||
PikaDrawable *drawable)
|
||||
{
|
||||
GtkWidget *chooser;
|
||||
|
||||
if (drawable_type == G_TYPE_NONE)
|
||||
drawable_type = PIKA_TYPE_DRAWABLE;
|
||||
|
||||
g_return_val_if_fail (g_type_is_a (drawable_type, PIKA_TYPE_DRAWABLE), NULL);
|
||||
g_return_val_if_fail (drawable == NULL ||
|
||||
g_type_is_a (G_TYPE_FROM_INSTANCE (drawable), drawable_type),
|
||||
NULL);
|
||||
|
||||
chooser = g_object_new (PIKA_TYPE_DRAWABLE_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"drawable", drawable,
|
||||
"drawable-type", drawable_type,
|
||||
NULL);
|
||||
|
||||
return chooser;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_drawable_chooser_get_drawable:
|
||||
* @chooser: A #PikaDrawableChooser
|
||||
*
|
||||
* Gets the currently selected drawable.
|
||||
*
|
||||
* Returns: (transfer none): an internal copy of the drawable which must not be freed.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
PikaDrawable *
|
||||
pika_drawable_chooser_get_drawable (PikaDrawableChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (PIKA_IS_DRAWABLE_CHOOSER (chooser), NULL);
|
||||
|
||||
return chooser->drawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_drawable_chooser_set_drawable:
|
||||
* @chooser: A #PikaDrawableChooser
|
||||
* @drawable: Drawable to set.
|
||||
*
|
||||
* Sets the currently selected drawable.
|
||||
* This will select the drawable in both the button and any chooser popup.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
void
|
||||
pika_drawable_chooser_set_drawable (PikaDrawableChooser *chooser,
|
||||
PikaDrawable *drawable)
|
||||
{
|
||||
g_return_if_fail (PIKA_IS_DRAWABLE_CHOOSER (chooser));
|
||||
g_return_if_fail (drawable == NULL || PIKA_IS_DRAWABLE (drawable));
|
||||
|
||||
chooser->drawable = drawable;
|
||||
|
||||
if (chooser->callback)
|
||||
pika_drawables_set_popup (chooser->callback, chooser->drawable);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (chooser), drawable_button_props[PROP_DRAWABLE]);
|
||||
|
||||
pika_drawable_chooser_draw (chooser);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_drawable_chooser_get_label:
|
||||
* @widget: A [class@DrawableChooser].
|
||||
*
|
||||
* Returns the label widget.
|
||||
*
|
||||
* Returns: (transfer none): the [class@Gtk.Widget] showing the label text.
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_drawable_chooser_get_label (PikaDrawableChooser *chooser)
|
||||
{
|
||||
g_return_val_if_fail (PIKA_IS_DRAWABLE_CHOOSER (chooser), NULL);
|
||||
|
||||
return chooser->label_widget;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static PikaValueArray *
|
||||
pika_temp_callback_run (PikaProcedure *procedure,
|
||||
PikaProcedureConfig *config,
|
||||
PikaDrawableChooser *chooser)
|
||||
{
|
||||
PikaDrawable *drawable;
|
||||
gboolean closing;
|
||||
|
||||
g_object_get (config,
|
||||
"drawable", &drawable,
|
||||
"closing", &closing,
|
||||
NULL);
|
||||
|
||||
g_object_set (chooser, "drawable", drawable, NULL);
|
||||
|
||||
if (closing)
|
||||
{
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
(GSourceFunc) pika_drawable_select_remove_after_run,
|
||||
g_strdup (pika_procedure_get_name (procedure)),
|
||||
g_free);
|
||||
g_clear_pointer (&chooser->callback, g_free);
|
||||
}
|
||||
|
||||
g_clear_object (&drawable);
|
||||
|
||||
return pika_procedure_new_return_values (procedure, PIKA_PDB_SUCCESS, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
pika_drawable_select_remove_after_run (const gchar *procedure_name)
|
||||
{
|
||||
pika_plug_in_remove_temp_procedure (pika_get_plug_in (), procedure_name);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_clicked (PikaDrawableChooser *chooser)
|
||||
{
|
||||
if (chooser->callback)
|
||||
{
|
||||
/* Popup already created. Calling setter raises the popup. */
|
||||
pika_drawables_set_popup (chooser->callback, chooser->drawable);
|
||||
}
|
||||
else
|
||||
{
|
||||
PikaPlugIn *plug_in = pika_get_plug_in ();
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (chooser));
|
||||
GBytes *handle = NULL;
|
||||
gchar *callback_name;
|
||||
PikaProcedure *callback_procedure;
|
||||
|
||||
if (PIKA_IS_DIALOG (toplevel))
|
||||
handle = pika_dialog_get_native_handle (PIKA_DIALOG (toplevel));
|
||||
|
||||
callback_name = pika_pdb_temp_procedure_name (pika_get_pdb ());
|
||||
callback_procedure = pika_procedure_new (plug_in,
|
||||
callback_name,
|
||||
PIKA_PDB_PROC_TYPE_TEMPORARY,
|
||||
(PikaRunFunc) pika_temp_callback_run,
|
||||
g_object_ref (chooser),
|
||||
(GDestroyNotify) g_object_unref);
|
||||
PIKA_PROC_ARG_DRAWABLE (callback_procedure, "drawable",
|
||||
"Drawable", "The selected drawable",
|
||||
TRUE, G_PARAM_READWRITE);
|
||||
PIKA_PROC_ARG_BOOLEAN (callback_procedure, "closing",
|
||||
"Closing", "If the dialog was closing",
|
||||
FALSE, G_PARAM_READWRITE);
|
||||
|
||||
pika_plug_in_add_temp_procedure (plug_in, callback_procedure);
|
||||
g_object_unref (callback_procedure);
|
||||
g_free (callback_name);
|
||||
|
||||
if (pika_drawables_popup (pika_procedure_get_name (callback_procedure), chooser->title,
|
||||
g_type_name (chooser->drawable_type), chooser->drawable, handle))
|
||||
{
|
||||
/* Allow callbacks to be watched */
|
||||
pika_plug_in_extension_enable (plug_in);
|
||||
|
||||
chooser->callback = g_strdup (pika_procedure_get_name (callback_procedure));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("%s: failed to open remote drawable select dialog.", G_STRFUNC);
|
||||
pika_plug_in_remove_temp_procedure (plug_in, pika_procedure_get_name (callback_procedure));
|
||||
return;
|
||||
}
|
||||
pika_drawables_set_popup (chooser->callback, chooser->drawable);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_draw (PikaDrawableChooser *chooser)
|
||||
{
|
||||
PikaPreviewArea *area = PIKA_PREVIEW_AREA (chooser->preview);
|
||||
GtkAllocation allocation;
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
|
||||
gtk_widget_get_allocation (chooser->preview, &allocation);
|
||||
|
||||
pika_drawable_chooser_get_thumbnail (chooser, allocation.width, allocation.height);
|
||||
|
||||
if (chooser->width < allocation.width ||
|
||||
chooser->height < allocation.height)
|
||||
{
|
||||
x = ((allocation.width - chooser->width) / 2);
|
||||
y = ((allocation.height - chooser->height) / 2);
|
||||
}
|
||||
pika_preview_area_reset (area);
|
||||
|
||||
if (chooser->thumbnail)
|
||||
{
|
||||
PikaImageType type;
|
||||
gint rowstride;
|
||||
|
||||
rowstride = chooser->width * chooser->bpp;
|
||||
switch (chooser->bpp)
|
||||
{
|
||||
case 1:
|
||||
type = PIKA_GRAY_IMAGE;
|
||||
break;
|
||||
case 2:
|
||||
type = PIKA_GRAYA_IMAGE;
|
||||
break;
|
||||
case 3:
|
||||
type = PIKA_RGB_IMAGE;
|
||||
break;
|
||||
case 4:
|
||||
type = PIKA_RGBA_IMAGE;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
pika_preview_area_draw (area, x, y, chooser->width, chooser->height, type,
|
||||
g_bytes_get_data (chooser->thumbnail, NULL), rowstride);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pika_drawable_chooser_get_thumbnail (PikaDrawableChooser *chooser,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (chooser->drawable == chooser->thumbnail_drawable &&
|
||||
chooser->width == width &&
|
||||
chooser->height == height)
|
||||
/* Let's assume drawable contents is not changing in a single run. */
|
||||
return;
|
||||
|
||||
g_clear_pointer (&chooser->thumbnail, g_bytes_unref);
|
||||
chooser->width = chooser->height = 0;
|
||||
|
||||
chooser->thumbnail_drawable = chooser->drawable;
|
||||
if (chooser->drawable)
|
||||
chooser->thumbnail = pika_drawable_get_thumbnail_data (chooser->drawable,
|
||||
width, height,
|
||||
&chooser->width,
|
||||
&chooser->height,
|
||||
&chooser->bpp);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikadrawablechooser.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_DRAWABLE_CHOOSER_H__
|
||||
#define __PIKA_DRAWABLE_CHOOSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_DRAWABLE_CHOOSER (pika_drawable_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaDrawableChooser, pika_drawable_chooser, PIKA, DRAWABLE_CHOOSER, GtkBox)
|
||||
|
||||
|
||||
GtkWidget * pika_drawable_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
GType drawable_type,
|
||||
PikaDrawable *drawable);
|
||||
|
||||
PikaDrawable * pika_drawable_chooser_get_drawable (PikaDrawableChooser *chooser);
|
||||
void pika_drawable_chooser_set_drawable (PikaDrawableChooser *chooser,
|
||||
PikaDrawable *drawable);
|
||||
GtkWidget * pika_drawable_chooser_get_label (PikaDrawableChooser *widget);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_DRAWABLE_CHOOSER_H__ */
|
|
@ -0,0 +1,151 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikadrawableselect_pdb.c
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is auto-generated by pdbgen.pl */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "stamp-pdbgen.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikadrawableselect
|
||||
* @title: pikadrawableselect
|
||||
* @short_description: Methods of a drawable chooser dialog
|
||||
*
|
||||
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* pika_drawables_popup:
|
||||
* @callback: The callback PDB proc to call when user chooses an drawable.
|
||||
* @popup_title: Title of the drawable selection dialog.
|
||||
* @drawable_type: The name of the PIKA_TYPE_DRAWABLE subtype.
|
||||
* @initial_drawable: The drawable to set as the initial choice.
|
||||
* @parent_window: An optional parent window handle for the popup to be set transient to.
|
||||
*
|
||||
* Invokes the drawable selection dialog.
|
||||
*
|
||||
* Opens a dialog letting a user choose an drawable.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
**/
|
||||
gboolean
|
||||
pika_drawables_popup (const gchar *callback,
|
||||
const gchar *popup_title,
|
||||
const gchar *drawable_type,
|
||||
PikaDrawable *initial_drawable,
|
||||
GBytes *parent_window)
|
||||
{
|
||||
PikaValueArray *args;
|
||||
PikaValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = pika_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, callback,
|
||||
G_TYPE_STRING, popup_title,
|
||||
G_TYPE_STRING, drawable_type,
|
||||
PIKA_TYPE_DRAWABLE, initial_drawable,
|
||||
G_TYPE_BYTES, parent_window,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _pika_pdb_run_procedure_array (pika_get_pdb (),
|
||||
"pika-drawables-popup",
|
||||
args);
|
||||
pika_value_array_unref (args);
|
||||
|
||||
success = PIKA_VALUES_GET_ENUM (return_vals, 0) == PIKA_PDB_SUCCESS;
|
||||
|
||||
pika_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_drawables_close_popup:
|
||||
* @callback: The name of the callback registered for this pop-up.
|
||||
*
|
||||
* Close the drawable selection dialog.
|
||||
*
|
||||
* Closes an open drawable selection dialog.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
**/
|
||||
gboolean
|
||||
pika_drawables_close_popup (const gchar *callback)
|
||||
{
|
||||
PikaValueArray *args;
|
||||
PikaValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = pika_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, callback,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _pika_pdb_run_procedure_array (pika_get_pdb (),
|
||||
"pika-drawables-close-popup",
|
||||
args);
|
||||
pika_value_array_unref (args);
|
||||
|
||||
success = PIKA_VALUES_GET_ENUM (return_vals, 0) == PIKA_PDB_SUCCESS;
|
||||
|
||||
pika_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_drawables_set_popup:
|
||||
* @callback: The name of the callback registered for this pop-up.
|
||||
* @drawable: The drawable to set as selected.
|
||||
*
|
||||
* Sets the selected drawable in a drawable selection dialog.
|
||||
*
|
||||
* Sets the selected drawable in a drawable selection dialog.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
**/
|
||||
gboolean
|
||||
pika_drawables_set_popup (const gchar *callback,
|
||||
PikaDrawable *drawable)
|
||||
{
|
||||
PikaValueArray *args;
|
||||
PikaValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = pika_value_array_new_from_types (NULL,
|
||||
G_TYPE_STRING, callback,
|
||||
PIKA_TYPE_DRAWABLE, drawable,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _pika_pdb_run_procedure_array (pika_get_pdb (),
|
||||
"pika-drawables-set-popup",
|
||||
args);
|
||||
pika_value_array_unref (args);
|
||||
|
||||
success = PIKA_VALUES_GET_ENUM (return_vals, 0) == PIKA_PDB_SUCCESS;
|
||||
|
||||
pika_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikadrawableselect_pdb.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is auto-generated by pdbgen.pl */
|
||||
|
||||
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pika.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_DRAWABLE_SELECT_PDB_H__
|
||||
#define __PIKA_DRAWABLE_SELECT_PDB_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
gboolean pika_drawables_popup (const gchar *callback,
|
||||
const gchar *popup_title,
|
||||
const gchar *drawable_type,
|
||||
PikaDrawable *initial_drawable,
|
||||
GBytes *parent_window);
|
||||
gboolean pika_drawables_close_popup (const gchar *callback);
|
||||
gboolean pika_drawables_set_popup (const gchar *callback,
|
||||
PikaDrawable *drawable);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_DRAWABLE_SELECT_PDB_H__ */
|
|
@ -0,0 +1,86 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikafont.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <pango/pangofc-fontmap.h>
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikafont.h"
|
||||
|
||||
struct _PikaFont
|
||||
{
|
||||
PikaResource parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (PikaFont, pika_font, PIKA_TYPE_RESOURCE);
|
||||
|
||||
|
||||
static void pika_font_class_init (PikaFontClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void pika_font_init (PikaFont *font)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_font_get_pango_font_description:
|
||||
* @font: (transfer none): the [class@Gimp.Font]
|
||||
*
|
||||
* Returns a [class@Pango.Font.Description] representing @font.
|
||||
*
|
||||
* Returns: (transfer full): a %PangoFontDescription representing @font.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
PangoFontDescription *
|
||||
pika_font_get_pango_font_description (PikaFont *font)
|
||||
{
|
||||
PangoFontDescription *desc = NULL;
|
||||
gchar *name = NULL;
|
||||
gchar *collection_id = NULL;
|
||||
gboolean is_internal;
|
||||
|
||||
is_internal = _pika_resource_get_identifiers (PIKA_RESOURCE (font),
|
||||
&name, &collection_id);
|
||||
/* TODO: we can't create fonts from internal fonts right now, but it should
|
||||
* actually be possible because these are in fact alias to non-internal fonts.
|
||||
* See #9985.
|
||||
*/
|
||||
if (! is_internal)
|
||||
{
|
||||
gchar *expanded_path;
|
||||
|
||||
expanded_path = pika_config_path_expand (collection_id, FALSE, NULL);
|
||||
if (expanded_path != NULL &&
|
||||
FcConfigAppFontAddFile (FcConfigGetCurrent (), (const FcChar8 *) expanded_path))
|
||||
desc = pango_font_description_from_string (name);
|
||||
|
||||
g_free (expanded_path);
|
||||
}
|
||||
|
||||
g_free (name);
|
||||
g_free (collection_id);
|
||||
|
||||
return desc;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikafont.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pika.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_FONT_H__
|
||||
#define __PIKA_FONT_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#include <libpika/pikaresource.h>
|
||||
|
||||
|
||||
#define PIKA_TYPE_FONT (pika_font_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaFont, pika_font, PIKA, FONT, PikaResource)
|
||||
|
||||
|
||||
PangoFontDescription * pika_font_get_pango_font_description (PikaFont *font);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_FONT_H__ */
|
|
@ -0,0 +1,158 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikafontchooser.c
|
||||
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikafontchooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikafontchooser
|
||||
* @title: PikaFontChooser
|
||||
* @short_description: A button which pops up a font selection dialog.
|
||||
*
|
||||
* A button which pops up a font selection dialog.
|
||||
**/
|
||||
|
||||
struct _PikaFontChooser
|
||||
{
|
||||
PikaResourceChooser parent_instance;
|
||||
|
||||
GtkWidget *label;
|
||||
};
|
||||
|
||||
|
||||
static void pika_font_chooser_draw_interior (PikaResourceChooser *self);
|
||||
|
||||
|
||||
static const GtkTargetEntry drag_target = { "application/x-pika-font-name", 0, 0 };
|
||||
|
||||
|
||||
G_DEFINE_FINAL_TYPE (PikaFontChooser, pika_font_chooser, PIKA_TYPE_RESOURCE_CHOOSER)
|
||||
|
||||
|
||||
static void
|
||||
pika_font_chooser_class_init (PikaFontChooserClass *klass)
|
||||
{
|
||||
PikaResourceChooserClass *superclass = PIKA_RESOURCE_CHOOSER_CLASS (klass);
|
||||
|
||||
superclass->draw_interior = pika_font_chooser_draw_interior;
|
||||
superclass->resource_type = PIKA_TYPE_FONT;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_font_chooser_init (PikaFontChooser *self)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *image;
|
||||
|
||||
button = gtk_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (self), button);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_container_add (GTK_CONTAINER (button), hbox);
|
||||
|
||||
image = gtk_image_new_from_icon_name (PIKA_ICON_FONT,
|
||||
GTK_ICON_SIZE_BUTTON);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
||||
|
||||
self->label = gtk_label_new ("unknown");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), self->label, TRUE, TRUE, 4);
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (self));
|
||||
|
||||
pika_resource_chooser_set_drag_target (PIKA_RESOURCE_CHOOSER (self),
|
||||
hbox, &drag_target);
|
||||
|
||||
pika_resource_chooser_set_clickable (PIKA_RESOURCE_CHOOSER (self), button);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_font_chooser_draw_interior (PikaResourceChooser *self)
|
||||
{
|
||||
PikaFontChooser *font_select= PIKA_FONT_CHOOSER (self);
|
||||
PikaResource *resource;
|
||||
gchar *name = NULL;
|
||||
|
||||
resource = pika_resource_chooser_get_resource (self);
|
||||
|
||||
if (resource)
|
||||
name = pika_resource_get_name (resource);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (font_select->label), name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pika_font_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @resource: (nullable): Initial font.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a font.
|
||||
* You can put this widget in a plug-in dialog.
|
||||
*
|
||||
* When font is NULL, initial choice is from context.
|
||||
*
|
||||
* Returns: A #GtkWidget that you can use in your UI.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_font_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource)
|
||||
{
|
||||
GtkWidget *chooser;
|
||||
|
||||
g_return_val_if_fail (resource == NULL || PIKA_IS_FONT (resource), NULL);
|
||||
|
||||
if (resource == NULL)
|
||||
resource = PIKA_RESOURCE (pika_context_get_font ());
|
||||
|
||||
if (title)
|
||||
chooser = g_object_new (PIKA_TYPE_FONT_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
else
|
||||
chooser = g_object_new (PIKA_TYPE_FONT_CHOOSER,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
|
||||
pika_font_chooser_draw_interior (PIKA_RESOURCE_CHOOSER (chooser));
|
||||
|
||||
return chooser;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikafontchooser.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_FONT_CHOOSER_H__
|
||||
#define __PIKA_FONT_CHOOSER_H__
|
||||
|
||||
#include <libpika/pikaresourcechooser.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_FONT_CHOOSER (pika_font_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaFontChooser, pika_font_chooser, PIKA, FONT_CHOOSER, PikaResourceChooser)
|
||||
|
||||
|
||||
GtkWidget * pika_font_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_FONT_CHOOSER_H__ */
|
|
@ -0,0 +1,42 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikagradient.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikagradient.h"
|
||||
|
||||
struct _PikaGradient
|
||||
{
|
||||
PikaResource parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (PikaGradient, pika_gradient, PIKA_TYPE_RESOURCE);
|
||||
|
||||
|
||||
static void pika_gradient_class_init (PikaGradientClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void pika_gradient_init (PikaGradient *gradient)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikagradient.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pika.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_GRADIENT_H__
|
||||
#define __PIKA_GRADIENT_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#include <libpika/pikaresource.h>
|
||||
|
||||
|
||||
#define PIKA_TYPE_GRADIENT (pika_gradient_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaGradient, pika_gradient, PIKA, GRADIENT, PikaResource)
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_GRADIENT_H__ */
|
|
@ -0,0 +1,303 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikagradientchooser.c
|
||||
* Copyright (C) 1998 Andy Thomas
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikagradientchooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikagradientchooser
|
||||
* @title: PikaGradientChooser
|
||||
* @short_description: A button which pops up a gradient select dialog.
|
||||
*
|
||||
* A button which pops up a gradient select dialog.
|
||||
**/
|
||||
|
||||
|
||||
struct _PikaGradientChooser
|
||||
{
|
||||
PikaResourceChooser parent_instance;
|
||||
|
||||
GtkWidget *preview;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void pika_gradient_chooser_draw_interior (PikaResourceChooser *self);
|
||||
|
||||
static void pika_gradient_select_preview_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
PikaGradientChooser *self);
|
||||
static gboolean pika_gradient_select_preview_draw_handler (GtkWidget *preview,
|
||||
cairo_t *cr,
|
||||
PikaGradientChooser *self);
|
||||
|
||||
|
||||
static const GtkTargetEntry drag_target = { "application/x-pika-gradient-name", 0 };
|
||||
|
||||
G_DEFINE_FINAL_TYPE (PikaGradientChooser,
|
||||
pika_gradient_chooser,
|
||||
PIKA_TYPE_RESOURCE_CHOOSER)
|
||||
|
||||
/* Initial dimensions of widget. */
|
||||
#define CELL_HEIGHT 18
|
||||
#define CELL_WIDTH 84
|
||||
|
||||
static void
|
||||
pika_gradient_chooser_class_init (PikaGradientChooserClass *klass)
|
||||
{
|
||||
PikaResourceChooserClass *superclass = PIKA_RESOURCE_CHOOSER_CLASS (klass);
|
||||
|
||||
superclass->draw_interior = pika_gradient_chooser_draw_interior;
|
||||
superclass->resource_type = PIKA_TYPE_GRADIENT;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_gradient_chooser_init (PikaGradientChooser *self)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (self), button);
|
||||
|
||||
self->preview = gtk_drawing_area_new ();
|
||||
gtk_widget_set_size_request (self->preview, CELL_WIDTH, CELL_HEIGHT);
|
||||
gtk_container_add (GTK_CONTAINER (button), self->preview);
|
||||
|
||||
g_signal_connect (self->preview, "size-allocate",
|
||||
G_CALLBACK (pika_gradient_select_preview_size_allocate),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->preview, "draw",
|
||||
G_CALLBACK (pika_gradient_select_preview_draw_handler),
|
||||
self);
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (self));
|
||||
|
||||
pika_resource_chooser_set_drag_target (PIKA_RESOURCE_CHOOSER (self),
|
||||
self->preview, &drag_target);
|
||||
|
||||
pika_resource_chooser_set_clickable (PIKA_RESOURCE_CHOOSER (self), button);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_gradient_chooser_draw_interior (PikaResourceChooser *self)
|
||||
{
|
||||
PikaGradientChooser *gradient_select = PIKA_GRADIENT_CHOOSER (self);
|
||||
|
||||
gtk_widget_queue_draw (gradient_select->preview);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pika_gradient_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @gradient: (nullable): Initial gradient.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a gradient.
|
||||
* You can use this widget in a table in a plug-in dialog.
|
||||
*
|
||||
* Returns: A #GtkWidget that you can use in your UI.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_gradient_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *gradient)
|
||||
{
|
||||
GtkWidget *self;
|
||||
|
||||
if (gradient == NULL)
|
||||
gradient = PIKA_RESOURCE (pika_context_get_gradient ());
|
||||
|
||||
if (title)
|
||||
self = g_object_new (PIKA_TYPE_GRADIENT_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"resource", gradient,
|
||||
NULL);
|
||||
else
|
||||
self = g_object_new (PIKA_TYPE_GRADIENT_CHOOSER,
|
||||
"label", label,
|
||||
"resource", gradient,
|
||||
NULL);
|
||||
|
||||
pika_gradient_chooser_draw_interior (PIKA_RESOURCE_CHOOSER (self));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
/* Get array of samples from self's gradient.
|
||||
* Return array and size at given handles.
|
||||
* Return success.
|
||||
*/
|
||||
static gboolean
|
||||
get_gradient_data (PikaGradientChooser *self,
|
||||
gint allocation_width,
|
||||
gint *sample_count,
|
||||
gdouble **sample_array)
|
||||
{
|
||||
PikaGradient *gradient;
|
||||
gboolean result;
|
||||
gdouble *samples;
|
||||
gint n_samples;
|
||||
|
||||
g_object_get (self, "resource", &gradient, NULL);
|
||||
|
||||
result = pika_gradient_get_uniform_samples (gradient,
|
||||
allocation_width,
|
||||
FALSE, /* not reversed. */
|
||||
&n_samples,
|
||||
&samples);
|
||||
|
||||
if (result)
|
||||
{
|
||||
/* Return array of samples to dereferenced handles. */
|
||||
*sample_array = samples;
|
||||
*sample_count = n_samples;
|
||||
}
|
||||
|
||||
g_object_unref (gradient);
|
||||
|
||||
/* When result is true, caller must free the array. */
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Called on widget resized. */
|
||||
static void
|
||||
pika_gradient_select_preview_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation,
|
||||
PikaGradientChooser *self)
|
||||
{
|
||||
/* Do nothing.
|
||||
*
|
||||
* In former code, we cached the gradient data in self, on allocate event.
|
||||
* But allocate event always seems to be paired with a draw event,
|
||||
* so there is no point in caching the gradient data.
|
||||
* And caching gradient data is a premature optimization,
|
||||
* without deep knowledge of Gtk and actual performance testing,
|
||||
* you can't know caching helps performance.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Draw array of samples.
|
||||
* This understands mostly cairo, and little about gradient.
|
||||
*/
|
||||
static void
|
||||
pika_gradient_select_preview_draw (cairo_t *cr,
|
||||
gint src_width,
|
||||
gint dest_width,
|
||||
gdouble *src)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_surface_t *surface;
|
||||
guchar *dest;
|
||||
gint x;
|
||||
|
||||
pattern = pika_cairo_checkerboard_create (cr, PIKA_CHECK_SIZE_SM, NULL, NULL);
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_paint (cr);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, src_width, 1);
|
||||
|
||||
for (x = 0, dest = cairo_image_surface_get_data (surface);
|
||||
x < src_width;
|
||||
x++, src += 4, dest += 4)
|
||||
{
|
||||
PikaRGB color;
|
||||
guchar r, g, b, a;
|
||||
|
||||
pika_rgba_set (&color, src[0], src[1], src[2], src[3]);
|
||||
pika_rgba_get_uchar (&color, &r, &g, &b, &a);
|
||||
|
||||
PIKA_CAIRO_ARGB32_SET_PIXEL (dest, r, g, b, a);
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty (surface);
|
||||
|
||||
pattern = cairo_pattern_create_for_surface (surface);
|
||||
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REFLECT);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
cairo_scale (cr, (gdouble) dest_width / (gdouble) src_width, 1.0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
cairo_paint (cr);
|
||||
}
|
||||
|
||||
/* Handles a draw signal.
|
||||
* Draw self, i.e. interior of button.
|
||||
*
|
||||
* Always returns FALSE, but doesn't draw when fail to get gradient data.
|
||||
*
|
||||
* Is passed neither gradient nor attributes of gradient: get them now from self.
|
||||
*/
|
||||
static gboolean
|
||||
pika_gradient_select_preview_draw_handler (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
PikaGradientChooser *self)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
|
||||
/* Attributes of the source.*/
|
||||
gdouble *src;
|
||||
gint n_samples;
|
||||
gint src_width;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
|
||||
if (!get_gradient_data (self, allocation.width, &n_samples, &src))
|
||||
return FALSE;
|
||||
|
||||
/* Width in pixels of src, since BPP is 4. */
|
||||
src_width = n_samples / 4;
|
||||
|
||||
pika_gradient_select_preview_draw (cr, src_width, allocation.width, src);
|
||||
|
||||
g_free (src);
|
||||
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikagradientchooser.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_GRADIENT_CHOOSER_H__
|
||||
#define __PIKA_GRADIENT_CHOOSER_H__
|
||||
|
||||
#include <libpika/pikaresourcechooser.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_GRADIENT_CHOOSER (pika_gradient_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaGradientChooser, pika_gradient_chooser, PIKA, GRADIENT_CHOOSER, PikaResourceChooser)
|
||||
|
||||
|
||||
GtkWidget * pika_gradient_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *gradient);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_GRADIENT_CHOOSER_H__ */
|
|
@ -0,0 +1,42 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapalette.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikapalette.h"
|
||||
|
||||
struct _PikaPalette
|
||||
{
|
||||
PikaResource parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (PikaPalette, pika_palette, PIKA_TYPE_RESOURCE);
|
||||
|
||||
|
||||
static void pika_palette_class_init (PikaPaletteClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void pika_palette_init (PikaPalette *palette)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapalette.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pika.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_PALETTE_H__
|
||||
#define __PIKA_PALETTE_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#include <libpika/pikaresource.h>
|
||||
|
||||
|
||||
#define PIKA_TYPE_PALETTE (pika_palette_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaPalette, pika_palette, PIKA, PALETTE, PikaResource)
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_PALETTE_H__ */
|
|
@ -0,0 +1,154 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapalettechooser.c
|
||||
* Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikapalettechooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikapalettechooser
|
||||
* @title: PikaPaletteChooser
|
||||
* @short_description: A button which pops up a palette selection dialog.
|
||||
*
|
||||
* A button which pops up a palette selection dialog.
|
||||
**/
|
||||
|
||||
struct _PikaPaletteChooser
|
||||
{
|
||||
PikaResourceChooser parent_instance;
|
||||
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
};
|
||||
|
||||
|
||||
static void pika_palette_chooser_draw_interior (PikaResourceChooser *self);
|
||||
|
||||
|
||||
static const GtkTargetEntry drag_target = { "application/x-pika-palette-name", 0, 0 };
|
||||
|
||||
|
||||
G_DEFINE_FINAL_TYPE (PikaPaletteChooser, pika_palette_chooser, PIKA_TYPE_RESOURCE_CHOOSER)
|
||||
|
||||
|
||||
static void
|
||||
pika_palette_chooser_class_init (PikaPaletteChooserClass *klass)
|
||||
{
|
||||
PikaResourceChooserClass *superclass = PIKA_RESOURCE_CHOOSER_CLASS (klass);
|
||||
|
||||
superclass->draw_interior = pika_palette_chooser_draw_interior;
|
||||
superclass->resource_type = PIKA_TYPE_PALETTE;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_palette_chooser_init (PikaPaletteChooser *self)
|
||||
{
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *image;
|
||||
|
||||
self->button = gtk_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (self), self->button);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_container_add (GTK_CONTAINER (self->button), hbox);
|
||||
|
||||
image = gtk_image_new_from_icon_name (PIKA_ICON_PALETTE,
|
||||
GTK_ICON_SIZE_BUTTON);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
||||
|
||||
self->label = gtk_label_new ("unknown");
|
||||
gtk_box_pack_start (GTK_BOX (hbox), self->label, TRUE, TRUE, 4);
|
||||
|
||||
gtk_widget_show_all (GTK_WIDGET (self));
|
||||
|
||||
pika_resource_chooser_set_drag_target (PIKA_RESOURCE_CHOOSER (self),
|
||||
hbox, &drag_target);
|
||||
pika_resource_chooser_set_clickable (PIKA_RESOURCE_CHOOSER (self), self->button);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_palette_chooser_draw_interior (PikaResourceChooser *self)
|
||||
{
|
||||
PikaPaletteChooser *palette_select= PIKA_PALETTE_CHOOSER (self);
|
||||
PikaResource *resource;
|
||||
gchar *name = NULL;
|
||||
|
||||
resource = pika_resource_chooser_get_resource (self);
|
||||
|
||||
if (resource)
|
||||
name = pika_resource_get_name (resource);
|
||||
|
||||
gtk_label_set_text (GTK_LABEL (palette_select->label), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_palette_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @resource: (nullable): Initial palette.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a palette.
|
||||
* You can put this widget in a table in a plug-in dialog.
|
||||
*
|
||||
* When palette is NULL, initial choice is from context.
|
||||
*
|
||||
* Returns: A #GtkWidget that you can use in your UI.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_palette_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource)
|
||||
{
|
||||
GtkWidget *self;
|
||||
|
||||
if (resource == NULL)
|
||||
resource = PIKA_RESOURCE (pika_context_get_palette ());
|
||||
|
||||
if (title)
|
||||
self = g_object_new (PIKA_TYPE_PALETTE_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
else
|
||||
self = g_object_new (PIKA_TYPE_PALETTE_CHOOSER,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
|
||||
pika_palette_chooser_draw_interior (PIKA_RESOURCE_CHOOSER (self));
|
||||
|
||||
return self;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapaletteselectbutton.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_PALETTE_CHOOSER_H__
|
||||
#define __PIKA_PALETTE_CHOOSER_H__
|
||||
|
||||
#include <libpika/pikaresourcechooser.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_PALETTE_CHOOSER (pika_palette_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaPaletteChooser, pika_palette_chooser, PIKA, PALETTE_CHOOSER, PikaResourceChooser)
|
||||
|
||||
|
||||
GtkWidget * pika_palette_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_PALETTE_CHOOSER_H__ */
|
|
@ -0,0 +1,207 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapattern.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikapattern.h"
|
||||
|
||||
struct _PikaPattern
|
||||
{
|
||||
PikaResource parent_instance;
|
||||
|
||||
/* Native size buffer of the pattern contents. */
|
||||
GeglBuffer *buffer;
|
||||
};
|
||||
|
||||
static void pika_pattern_finalize (GObject *object);
|
||||
static void pika_pattern_get_data (PikaPattern *pattern);
|
||||
static GeglBuffer * pika_pattern_scale (GeglBuffer *buffer,
|
||||
gint max_width,
|
||||
gint max_height);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (PikaPattern, pika_pattern, PIKA_TYPE_RESOURCE);
|
||||
|
||||
|
||||
static void pika_pattern_class_init (PikaPatternClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = pika_pattern_finalize;
|
||||
}
|
||||
|
||||
static void pika_pattern_init (PikaPattern *pattern)
|
||||
{
|
||||
pattern->buffer = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pattern_finalize (GObject *object)
|
||||
{
|
||||
PikaPattern *pattern = PIKA_PATTERN (object);
|
||||
|
||||
g_clear_object (&pattern->buffer);
|
||||
|
||||
G_OBJECT_CLASS (pika_pattern_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* pika_pattern_get_buffer:
|
||||
* @pattern: a [class@Pattern].
|
||||
* @max_width: a maximum width for the returned buffer.
|
||||
* @max_height: a maximum height for the returned buffer.
|
||||
* @format: an optional Babl format.
|
||||
*
|
||||
* Gets pixel data of the pattern within the bounding box specified by @max_width
|
||||
* and @max_height. The data will be scaled down so that it fits within this
|
||||
* size without changing its ratio. If the pattern is smaller than this size to
|
||||
* begin with, it will not be scaled up.
|
||||
*
|
||||
* If @max_width or @max_height are %NULL, the buffer is returned in the pattern's
|
||||
* native size.
|
||||
*
|
||||
* Make sure you called [func@Gegl.init] before calling any function using
|
||||
* `GEGL`.
|
||||
*
|
||||
* Returns: (transfer full): a [class@Gegl.Buffer].
|
||||
*/
|
||||
GeglBuffer *
|
||||
pika_pattern_get_buffer (PikaPattern *pattern,
|
||||
gint max_width,
|
||||
gint max_height,
|
||||
const Babl *format)
|
||||
{
|
||||
pika_pattern_get_data (pattern);
|
||||
|
||||
g_return_val_if_fail (pattern->buffer != NULL, NULL);
|
||||
|
||||
if (max_width == 0 || max_height == 0 ||
|
||||
(gegl_buffer_get_width (pattern->buffer) <= max_width &&
|
||||
gegl_buffer_get_height (pattern->buffer) <= max_height))
|
||||
return gegl_buffer_dup (pattern->buffer);
|
||||
|
||||
return pika_pattern_scale (pattern->buffer, max_width, max_height);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pattern_get_data (PikaPattern *pattern)
|
||||
{
|
||||
gint width;
|
||||
gint height;
|
||||
gint bpp;
|
||||
GBytes *bytes;
|
||||
const guchar *pixels;
|
||||
gsize pixels_size;
|
||||
const Babl *format;
|
||||
|
||||
/*
|
||||
* This check assumes that the pattern contents doesn't change, which is not a
|
||||
* perfect assumption. We could maybe add a PDB call which would return
|
||||
* the new pattern data only if it changed since last call (which can be
|
||||
* verified with some kind of internal runtime version to pass from one call
|
||||
* to another). TODO
|
||||
*/
|
||||
if (pattern->buffer != NULL)
|
||||
return;
|
||||
|
||||
g_clear_object (&pattern->buffer);
|
||||
|
||||
_pika_pattern_get_pixels (pattern, &width, &height, &bpp, &bytes);
|
||||
pixels = g_bytes_unref_to_data (bytes, &pixels_size);
|
||||
|
||||
/* It's an ugly way to determine the proper format but pika_pattern_get_pixels()
|
||||
* doesn't give more info.
|
||||
*/
|
||||
switch (bpp)
|
||||
{
|
||||
case 1:
|
||||
format = babl_format ("Y' u8");
|
||||
break;
|
||||
case 2:
|
||||
format = babl_format ("Y'A u8");
|
||||
break;
|
||||
case 3:
|
||||
format = babl_format ("R'G'B' u8");
|
||||
break;
|
||||
case 4:
|
||||
format = babl_format ("R'G'B'A u8");
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
pattern->buffer = gegl_buffer_linear_new_from_data ((const gpointer) pixels, format,
|
||||
GEGL_RECTANGLE (0, 0, width, height),
|
||||
0, g_free, NULL);
|
||||
}
|
||||
|
||||
static GeglBuffer *
|
||||
pika_pattern_scale (GeglBuffer *buffer,
|
||||
gint max_width,
|
||||
gint max_height)
|
||||
{
|
||||
GeglBuffer *scaled = NULL;
|
||||
GeglNode *graph;
|
||||
GeglNode *source;
|
||||
GeglNode *op;
|
||||
GeglNode *sink;
|
||||
gdouble width;
|
||||
gdouble height;
|
||||
gdouble scale;
|
||||
|
||||
height = (gdouble) max_height;
|
||||
width = (gdouble) gegl_buffer_get_width (buffer) / gegl_buffer_get_height (buffer) * height;
|
||||
if (width > (gdouble) max_width)
|
||||
{
|
||||
width = (gdouble) max_width;
|
||||
height = (gdouble) gegl_buffer_get_height (buffer) / gegl_buffer_get_width (buffer) * width;
|
||||
}
|
||||
scale = width / gegl_buffer_get_width (buffer);
|
||||
|
||||
graph = gegl_node_new ();
|
||||
source = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-source",
|
||||
"buffer", buffer,
|
||||
NULL);
|
||||
op = gegl_node_new_child (graph,
|
||||
"operation", "gegl:scale-ratio",
|
||||
"origin-x", 0.0,
|
||||
"origin-y", 0.0,
|
||||
"sampler", PIKA_INTERPOLATION_LINEAR,
|
||||
"abyss-policy", GEGL_ABYSS_CLAMP,
|
||||
"x", scale,
|
||||
"y", scale,
|
||||
NULL);
|
||||
sink = gegl_node_new_child (graph,
|
||||
"operation", "gegl:buffer-sink",
|
||||
"buffer", &scaled,
|
||||
"format", gegl_buffer_get_format (buffer),
|
||||
NULL);
|
||||
gegl_node_link_many (source, op, sink, NULL);
|
||||
gegl_node_process (sink);
|
||||
|
||||
g_object_unref (graph);
|
||||
|
||||
return scaled;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapattern.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pika.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_PATTERN_H__
|
||||
#define __PIKA_PATTERN_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#include <libpika/pikaresource.h>
|
||||
|
||||
|
||||
#define PIKA_TYPE_PATTERN (pika_pattern_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaPattern, pika_pattern, PIKA, PATTERN, PikaResource)
|
||||
|
||||
|
||||
|
||||
GeglBuffer * pika_pattern_get_buffer (PikaPattern *pattern,
|
||||
gint max_width,
|
||||
gint max_height,
|
||||
const Babl *format) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_PATTERN_H__ */
|
|
@ -0,0 +1,381 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapatternchooser.c
|
||||
* Copyright (C) 1998 Andy Thomas
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikapatternchooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikapatternchooser
|
||||
* @title: PikaPatternChooser
|
||||
* @short_description: A button which pops up a pattern selection dialog.
|
||||
*
|
||||
* A button which pops up a pattern selection dialog.
|
||||
*
|
||||
* Note that this widget draws itself using `GEGL` code. You **must** call
|
||||
* [func@Gegl.init] first to be able to use this chooser.
|
||||
**/
|
||||
|
||||
#define CELL_SIZE 40
|
||||
|
||||
struct _PikaPatternChooser
|
||||
{
|
||||
PikaResourceChooser parent_instance;
|
||||
|
||||
GtkWidget *preview;
|
||||
GtkWidget *popup;
|
||||
|
||||
PikaPattern *pattern;
|
||||
GeglBuffer *buffer;
|
||||
gint width;
|
||||
gint height;
|
||||
};
|
||||
|
||||
/* local */
|
||||
|
||||
static gboolean pika_pattern_select_on_preview_events (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
PikaPatternChooser *button);
|
||||
|
||||
/* local drawing methods. */
|
||||
static void pika_pattern_select_preview_fill_draw (PikaPatternChooser *chooser,
|
||||
PikaPreviewArea *area);
|
||||
|
||||
static void pika_pattern_chooser_draw (PikaResourceChooser *self);
|
||||
static void pika_pattern_chooser_get_pattern_image (PikaPatternChooser *self,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
/* Popup methods. */
|
||||
static void pika_pattern_chooser_open_popup (PikaPatternChooser *button,
|
||||
gint x,
|
||||
gint y);
|
||||
static void pika_pattern_chooser_close_popup (PikaPatternChooser *button);
|
||||
|
||||
|
||||
/* A GtkTargetEntry has a string and two ints.
|
||||
* This is one, but we treat it as an array.
|
||||
*/
|
||||
static const GtkTargetEntry drag_target = { "application/x-pika-pattern-name", 0, 0 };
|
||||
|
||||
G_DEFINE_FINAL_TYPE (PikaPatternChooser, pika_pattern_chooser, PIKA_TYPE_RESOURCE_CHOOSER)
|
||||
|
||||
|
||||
static void
|
||||
pika_pattern_chooser_class_init (PikaPatternChooserClass *klass)
|
||||
{
|
||||
PikaResourceChooserClass *superclass = PIKA_RESOURCE_CHOOSER_CLASS (klass);
|
||||
|
||||
superclass->draw_interior = pika_pattern_chooser_draw;
|
||||
superclass->resource_type = PIKA_TYPE_PATTERN;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pattern_chooser_init (PikaPatternChooser *self)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *button;
|
||||
|
||||
frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (self), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
self->preview = pika_preview_area_new ();
|
||||
gtk_widget_add_events (self->preview,
|
||||
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
|
||||
gtk_widget_set_size_request (self->preview, CELL_SIZE, CELL_SIZE);
|
||||
gtk_container_add (GTK_CONTAINER (frame), self->preview);
|
||||
gtk_widget_show (self->preview);
|
||||
|
||||
g_signal_connect_swapped (self->preview, "size-allocate",
|
||||
G_CALLBACK (pika_pattern_chooser_draw),
|
||||
self);
|
||||
|
||||
g_signal_connect (self->preview, "event",
|
||||
G_CALLBACK (pika_pattern_select_on_preview_events),
|
||||
self);
|
||||
|
||||
button = gtk_button_new_with_mnemonic (_("_Browse..."));
|
||||
gtk_box_pack_start (GTK_BOX (self), button, FALSE, FALSE, 0);
|
||||
|
||||
pika_resource_chooser_set_drag_target (PIKA_RESOURCE_CHOOSER (self),
|
||||
self->preview, &drag_target);
|
||||
|
||||
pika_resource_chooser_set_clickable (PIKA_RESOURCE_CHOOSER (self), button);
|
||||
gtk_widget_show (button);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_pattern_chooser_new:
|
||||
* @title: (nullable): Title of the dialog to use or %NULL to use the default title.
|
||||
* @label: (nullable): Button label or %NULL for no label.
|
||||
* @resource: (nullable): Initial pattern.
|
||||
*
|
||||
* Creates a new #GtkWidget that lets a user choose a pattern.
|
||||
* You can put this widget in a table in a plug-in dialog.
|
||||
*
|
||||
* When pattern is NULL, initial choice is from context.
|
||||
*
|
||||
* Returns: A #GtkWidget that you can use in your UI.
|
||||
*
|
||||
* Since: 2.4
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_pattern_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource)
|
||||
{
|
||||
GtkWidget *self;
|
||||
|
||||
if (resource == NULL)
|
||||
resource = PIKA_RESOURCE (pika_context_get_pattern ());
|
||||
g_return_val_if_fail (PIKA_IS_PATTERN (resource), NULL);
|
||||
|
||||
if (title)
|
||||
self = g_object_new (PIKA_TYPE_PATTERN_CHOOSER,
|
||||
"title", title,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
else
|
||||
self = g_object_new (PIKA_TYPE_PATTERN_CHOOSER,
|
||||
"label", label,
|
||||
"resource", resource,
|
||||
NULL);
|
||||
|
||||
pika_pattern_chooser_draw (PIKA_RESOURCE_CHOOSER (self));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pika_pattern_chooser_draw (PikaResourceChooser *chooser)
|
||||
{
|
||||
PikaPatternChooser *pchooser = PIKA_PATTERN_CHOOSER (chooser);
|
||||
GtkAllocation allocation;
|
||||
|
||||
gtk_widget_get_allocation (pchooser->preview, &allocation);
|
||||
|
||||
pika_pattern_chooser_get_pattern_image (pchooser, allocation.width, allocation.height);
|
||||
pika_pattern_select_preview_fill_draw (pchooser, PIKA_PREVIEW_AREA (pchooser->preview));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pattern_chooser_get_pattern_image (PikaPatternChooser *chooser,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
PikaPattern *pattern;
|
||||
|
||||
g_object_get (chooser, "resource", &pattern, NULL);
|
||||
|
||||
if (chooser->pattern == pattern &&
|
||||
chooser->width == width &&
|
||||
chooser->height == height)
|
||||
{
|
||||
/* Let's assume pattern contents is not changing in a single run. */
|
||||
g_object_unref (pattern);
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_object (&chooser->buffer);
|
||||
|
||||
chooser->pattern = pattern;
|
||||
chooser->buffer = pika_pattern_get_buffer (pattern, width, height, NULL);
|
||||
chooser->width = gegl_buffer_get_width (chooser->buffer);
|
||||
chooser->height = gegl_buffer_get_height (chooser->buffer);
|
||||
|
||||
g_object_unref (pattern);
|
||||
}
|
||||
|
||||
/* On mouse events in self's preview, popup a zoom view of entire pattern */
|
||||
static gboolean
|
||||
pika_pattern_select_on_preview_events (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
PikaPatternChooser *self)
|
||||
{
|
||||
GdkEventButton *bevent;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case GDK_BUTTON_PRESS:
|
||||
bevent = (GdkEventButton *) event;
|
||||
|
||||
if (bevent->button == 1)
|
||||
{
|
||||
gtk_grab_add (widget);
|
||||
pika_pattern_chooser_open_popup (self,
|
||||
bevent->x, bevent->y);
|
||||
}
|
||||
break;
|
||||
|
||||
case GDK_BUTTON_RELEASE:
|
||||
bevent = (GdkEventButton *) event;
|
||||
|
||||
if (bevent->button == 1)
|
||||
{
|
||||
gtk_grab_remove (widget);
|
||||
pika_pattern_chooser_close_popup (self);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Fill a PikaPreviewArea with a image then draw. */
|
||||
static void
|
||||
pika_pattern_select_preview_fill_draw (PikaPatternChooser *chooser,
|
||||
PikaPreviewArea *area)
|
||||
{
|
||||
GeglBuffer *src_buffer;
|
||||
const Babl *format;
|
||||
const Babl *model;
|
||||
guchar *src;
|
||||
PikaImageType type;
|
||||
gint rowstride;
|
||||
GtkAllocation allocation;
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
|
||||
gtk_widget_get_allocation (GTK_WIDGET (area), &allocation);
|
||||
|
||||
/* Fill with white. */
|
||||
if (chooser->width < allocation.width ||
|
||||
chooser->height < allocation.height)
|
||||
{
|
||||
pika_preview_area_fill (area,
|
||||
0, 0,
|
||||
allocation.width,
|
||||
allocation.height,
|
||||
0xFF, 0xFF, 0xFF);
|
||||
|
||||
x = ((allocation.width - chooser->width) / 2);
|
||||
y = ((allocation.height - chooser->height) / 2);
|
||||
}
|
||||
|
||||
/* Draw the pattern. */
|
||||
src_buffer = chooser->buffer;
|
||||
format = gegl_buffer_get_format (src_buffer);
|
||||
rowstride = chooser->width * babl_format_get_bytes_per_pixel (format);
|
||||
model = babl_format_get_model (format);
|
||||
|
||||
if (model == babl_model ("R'G'B'"))
|
||||
type = PIKA_RGB_IMAGE;
|
||||
else if (model == babl_model ("R'G'B'A"))
|
||||
type = PIKA_RGBA_IMAGE;
|
||||
else if (model == babl_model ("Y'"))
|
||||
type = PIKA_GRAY_IMAGE;
|
||||
else if (model == babl_model ("Y'A"))
|
||||
type = PIKA_GRAYA_IMAGE;
|
||||
else
|
||||
/* I just know that we can't have other formats because I set it up this way
|
||||
* in pika_pattern_get_buffer(). If we make the latter more generic, able to
|
||||
* return more types of pixel data, this should be reviewed. XXX
|
||||
*/
|
||||
g_return_if_reached ();
|
||||
|
||||
src = g_try_malloc (sizeof (guchar) * rowstride * chooser->height);
|
||||
|
||||
gegl_buffer_get (chooser->buffer, NULL, 1.0, format, src, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
|
||||
pika_preview_area_draw (area, x, y, chooser->width, chooser->height, type, src, rowstride);
|
||||
|
||||
g_free (src);
|
||||
}
|
||||
|
||||
/* popup methods. */
|
||||
|
||||
static void
|
||||
pika_pattern_chooser_open_popup (PikaPatternChooser *chooser,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *preview;
|
||||
GdkMonitor *monitor;
|
||||
GdkRectangle workarea;
|
||||
gint x_org;
|
||||
gint y_org;
|
||||
|
||||
if (chooser->popup)
|
||||
pika_pattern_chooser_close_popup (chooser);
|
||||
|
||||
if (chooser->width <= CELL_SIZE && chooser->height <= CELL_SIZE)
|
||||
return;
|
||||
|
||||
chooser->popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_type_hint (GTK_WINDOW (chooser->popup), GDK_WINDOW_TYPE_HINT_DND);
|
||||
gtk_window_set_screen (GTK_WINDOW (chooser->popup),
|
||||
gtk_widget_get_screen (GTK_WIDGET (chooser)));
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add (GTK_CONTAINER (chooser->popup), frame);
|
||||
gtk_widget_show (frame);
|
||||
|
||||
preview = pika_preview_area_new ();
|
||||
gtk_widget_set_size_request (preview, chooser->width, chooser->height);
|
||||
gtk_container_add (GTK_CONTAINER (frame), preview);
|
||||
gtk_widget_show (preview);
|
||||
|
||||
/* decide where to put the popup: near the preview i.e. at mousedown coords */
|
||||
gdk_window_get_origin (gtk_widget_get_window (chooser->preview),
|
||||
&x_org, &y_org);
|
||||
|
||||
monitor = pika_widget_get_monitor (GTK_WIDGET (chooser));
|
||||
gdk_monitor_get_workarea (monitor, &workarea);
|
||||
|
||||
x = x_org + x - (chooser->width / 2);
|
||||
y = y_org + y - (chooser->height / 2);
|
||||
|
||||
x = CLAMP (x, workarea.x, workarea.x + workarea.width - chooser->width);
|
||||
y = CLAMP (y, workarea.y, workarea.y + workarea.height - chooser->height);
|
||||
|
||||
gtk_window_move (GTK_WINDOW (chooser->popup), x, y);
|
||||
|
||||
gtk_widget_show (chooser->popup);
|
||||
|
||||
/* Draw popup now. Usual events do not cause a draw. */
|
||||
pika_pattern_select_preview_fill_draw (chooser, PIKA_PREVIEW_AREA (preview));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_pattern_chooser_close_popup (PikaPatternChooser *self)
|
||||
{
|
||||
g_clear_pointer (&self->popup, gtk_widget_destroy);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapatternchooser.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_PATTERN_CHOOSER_H__
|
||||
#define __PIKA_PATTERN_CHOOSER_H__
|
||||
|
||||
#include <libpika/pikaresourcechooser.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_PATTERN_CHOOSER (pika_pattern_chooser_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaPatternChooser, pika_pattern_chooser, PIKA, PATTERN_CHOOSER, PikaResourceChooser)
|
||||
|
||||
|
||||
GtkWidget * pika_pattern_chooser_new (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *resource);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_PATTERN_CHOOSER_H__ */
|
|
@ -0,0 +1,273 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapropwidgets.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libpika/pikaui.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
/*
|
||||
* This is a complement of libpikawidgets/pikapropwidgets.c
|
||||
* These are property functions for types from libpika, such as
|
||||
* [class@Gimp.Resource] or [class@Gimp.Item] subclasses.
|
||||
*/
|
||||
|
||||
|
||||
typedef GtkWidget* (*PikaResourceWidgetCreator) (const gchar *title,
|
||||
const gchar *label,
|
||||
PikaResource *initial_resource);
|
||||
|
||||
|
||||
/* utility function prototypes */
|
||||
|
||||
static GtkWidget * pika_prop_resource_chooser_factory (PikaResourceWidgetCreator widget_creator_func,
|
||||
GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
static gchar * pika_utils_make_canonical_menu_label (const gchar *path);
|
||||
|
||||
|
||||
/**
|
||||
* pika_prop_brush_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Brush] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@Gimp.Brush.Chooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.BrushChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_prop_brush_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
return pika_prop_resource_chooser_factory (pika_brush_chooser_new,
|
||||
config, property_name, chooser_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_prop_font_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Font] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@GimpUi.FontChooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.FontChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_prop_font_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
return pika_prop_resource_chooser_factory (pika_font_chooser_new,
|
||||
config, property_name, chooser_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_prop_gradient_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Gradient] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@GimpUi.GradientChooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.GradientChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_prop_gradient_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
return pika_prop_resource_chooser_factory (pika_gradient_chooser_new,
|
||||
config, property_name, chooser_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_prop_palette_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Palette] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@GimpUi.PaletteChooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.PaletteChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_prop_palette_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
return pika_prop_resource_chooser_factory (pika_palette_chooser_new,
|
||||
config, property_name, chooser_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_prop_pattern_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Pattern] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@GimpUi.PatternChooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.PatternChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_prop_pattern_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
return pika_prop_resource_chooser_factory (pika_pattern_chooser_new,
|
||||
config, property_name, chooser_title);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_prop_drawable_chooser_new:
|
||||
* @config: Object to which property is attached.
|
||||
* @property_name: Name of a [class@Gimp.Drawable] property.
|
||||
* @chooser_title: (nullable): title for the poppable dialog.
|
||||
*
|
||||
* Creates a [class@GimpUi.DrawableChooser] controlled by the specified property.
|
||||
*
|
||||
* Returns: (transfer full): A new [class@GimpUi.DrawableChooser].
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_prop_drawable_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
GParamSpec *param_spec;
|
||||
GtkWidget *prop_chooser;
|
||||
PikaDrawable *initial_drawable = NULL;
|
||||
gchar *title = NULL;
|
||||
const gchar *label;
|
||||
|
||||
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
|
||||
property_name);
|
||||
|
||||
g_return_val_if_fail (param_spec != NULL, NULL);
|
||||
g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_OBJECT) &&
|
||||
g_type_is_a (param_spec->value_type, PIKA_TYPE_DRAWABLE), NULL);
|
||||
|
||||
g_object_get (config,
|
||||
property_name, &initial_drawable,
|
||||
NULL);
|
||||
|
||||
label = g_param_spec_get_nick (param_spec);
|
||||
|
||||
if (chooser_title == NULL)
|
||||
{
|
||||
gchar *canonical;
|
||||
|
||||
canonical = pika_utils_make_canonical_menu_label (label);
|
||||
if (g_type_is_a (param_spec->value_type, PIKA_TYPE_LAYER))
|
||||
title = g_strdup_printf (_("Choose layer: %s"), canonical);
|
||||
if (g_type_is_a (param_spec->value_type, PIKA_TYPE_CHANNEL))
|
||||
title = g_strdup_printf (_("Choose channel: %s"), canonical);
|
||||
else
|
||||
title = g_strdup_printf (_("Choose drawable: %s"), canonical);
|
||||
g_free (canonical);
|
||||
}
|
||||
else
|
||||
{
|
||||
title = g_strdup (chooser_title);
|
||||
}
|
||||
|
||||
prop_chooser = pika_drawable_chooser_new (title, label, param_spec->value_type, initial_drawable);
|
||||
g_clear_object (&initial_drawable);
|
||||
g_free (title);
|
||||
|
||||
g_object_bind_property (prop_chooser, "drawable",
|
||||
config, property_name,
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
||||
return prop_chooser;
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* private utility functions */
|
||||
/*******************************/
|
||||
|
||||
static GtkWidget *
|
||||
pika_prop_resource_chooser_factory (PikaResourceWidgetCreator widget_creator_func,
|
||||
GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title)
|
||||
{
|
||||
GParamSpec *param_spec;
|
||||
GtkWidget *prop_chooser;
|
||||
PikaResource *initial_resource;
|
||||
const gchar *label;
|
||||
|
||||
param_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (config),
|
||||
property_name);
|
||||
|
||||
g_return_val_if_fail (param_spec != NULL, NULL);
|
||||
g_return_val_if_fail (g_type_is_a (G_TYPE_FROM_INSTANCE (param_spec), G_TYPE_PARAM_OBJECT) &&
|
||||
g_type_is_a (param_spec->value_type, PIKA_TYPE_RESOURCE), NULL);
|
||||
|
||||
g_object_get (config,
|
||||
property_name, &initial_resource,
|
||||
NULL);
|
||||
|
||||
label = g_param_spec_get_nick (param_spec);
|
||||
|
||||
/* Create the wrapped widget. For example, call pika_font_chooser_new.
|
||||
* When initial_resource is NULL, the widget creator will set it's resource
|
||||
* property from context.
|
||||
*/
|
||||
prop_chooser = widget_creator_func (chooser_title, label, initial_resource);
|
||||
g_clear_object (&initial_resource);
|
||||
|
||||
g_object_bind_property (prop_chooser, "resource",
|
||||
config, property_name,
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
|
||||
return prop_chooser;
|
||||
}
|
||||
|
||||
/* This is a copy of the similarly-named function in app/widgets/pikawidgets-utils.c
|
||||
* I hesitated to put this maybe in libpikawidgets/pikawidgetsutils.h but for
|
||||
* now, let's not. If it's useful to more people, it's always easier to move the
|
||||
* function in rather than deprecating it.
|
||||
*/
|
||||
static gchar *
|
||||
pika_utils_make_canonical_menu_label (const gchar *path)
|
||||
{
|
||||
gchar **split_path;
|
||||
gchar *canon_path;
|
||||
|
||||
/* The first underscore of each path item is a mnemonic. */
|
||||
split_path = g_strsplit (path, "_", 2);
|
||||
canon_path = g_strjoinv ("", split_path);
|
||||
g_strfreev (split_path);
|
||||
|
||||
return canon_path;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikapropwidgets.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __PIKA_PROP_WIDGETS_H__
|
||||
#define __PIKA_PROP_WIDGETS_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
/* PikaParamResource */
|
||||
|
||||
GtkWidget * pika_prop_brush_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
GtkWidget * pika_prop_font_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
GtkWidget * pika_prop_gradient_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
GtkWidget * pika_prop_palette_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
GtkWidget * pika_prop_pattern_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
|
||||
GtkWidget * pika_prop_drawable_chooser_new (GObject *config,
|
||||
const gchar *property_name,
|
||||
const gchar *chooser_title);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_PROP_WIDGETS_H__ */
|
|
@ -0,0 +1,622 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikawidgets/pikawidgets.h"
|
||||
|
||||
#include "pika.h"
|
||||
|
||||
#include "pikauitypes.h"
|
||||
#include "pikaresourcechooser.h"
|
||||
#include "pikauimarshal.h"
|
||||
|
||||
#include "libpika-intl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikaresourcechooser
|
||||
* @title: PikaResourceChooser
|
||||
* @short_description: Base class for buttons that popup a resource
|
||||
* selection dialog.
|
||||
*
|
||||
* A button which pops up a resource selection dialog.
|
||||
*
|
||||
* Responsibilities:
|
||||
*
|
||||
* - implementing outer container widget,
|
||||
* - managing clicks and popping up a remote chooser,
|
||||
* - having a resource property,
|
||||
* - signaling when user selects resource
|
||||
* - receiving drag,
|
||||
* - triggering draws of the button interior (by subclass) and draws of remote popup chooser.
|
||||
*
|
||||
* Collaborations:
|
||||
*
|
||||
* - owned by PikaProcedureDialog via PikaPropWidget
|
||||
* - resource property usually bound to a PikaConfig for a PikaPluginProcedure.
|
||||
* - communicates using PikaResourceSelect with remote PikaPDBDialog,
|
||||
* to choose an installed PikaResource owned by core.
|
||||
*
|
||||
* Subclass responsibilities:
|
||||
*
|
||||
* - creating interior widgets
|
||||
* - drawing the interior (a preview of the chosen resource)
|
||||
* - declaring which interior widgets are drag destinations
|
||||
* - declaring which interior widgets are clickable (generate "clicked" signal)
|
||||
* - generate "clicked" (delegating to GtkButton or implementing from mouse events)
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
RESOURCE_SET,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_TITLE,
|
||||
PROP_LABEL,
|
||||
PROP_RESOURCE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PikaResource *resource;
|
||||
gchar *title;
|
||||
gchar *label;
|
||||
gchar *callback;
|
||||
|
||||
GtkWidget *label_widget;
|
||||
} PikaResourceChooserPrivate;
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void pika_resource_chooser_constructed (GObject *object);
|
||||
static void pika_resource_chooser_dispose (GObject *object);
|
||||
static void pika_resource_chooser_finalize (GObject *object);
|
||||
|
||||
static void pika_resource_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void pika_resource_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static void pika_resource_chooser_clicked (PikaResourceChooser *self);
|
||||
|
||||
static void pika_resource_chooser_callback (PikaResource *resource,
|
||||
gboolean dialog_closing,
|
||||
gpointer user_data);
|
||||
|
||||
static void pika_resource_select_drag_data_received (PikaResourceChooser *self,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData *selection,
|
||||
guint info,
|
||||
guint time);
|
||||
|
||||
static void pika_resource_chooser_set_remote_dialog (PikaResourceChooser *self,
|
||||
PikaResource *resource);
|
||||
|
||||
|
||||
static guint resource_button_signals[LAST_SIGNAL] = { 0 };
|
||||
static GParamSpec *resource_button_props[N_PROPS] = { NULL, };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (PikaResourceChooser, pika_resource_chooser, GTK_TYPE_BOX)
|
||||
|
||||
|
||||
static void
|
||||
pika_resource_chooser_class_init (PikaResourceChooserClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = pika_resource_chooser_constructed;
|
||||
object_class->dispose = pika_resource_chooser_dispose;
|
||||
object_class->finalize = pika_resource_chooser_finalize;
|
||||
object_class->set_property = pika_resource_chooser_set_property;
|
||||
object_class->get_property = pika_resource_chooser_get_property;
|
||||
|
||||
klass->resource_set = NULL;
|
||||
|
||||
/**
|
||||
* PikaResourceChooser:title:
|
||||
*
|
||||
* The title to be used for the resource selection popup dialog.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
resource_button_props[PROP_TITLE] =
|
||||
g_param_spec_string ("title",
|
||||
"Title",
|
||||
"The title to be used for the resource selection popup dialog",
|
||||
"Resource Selection",
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* PikaResourceChooser:label:
|
||||
*
|
||||
* Label text with mnemonic.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
resource_button_props[PROP_LABEL] =
|
||||
g_param_spec_string ("label",
|
||||
"Label",
|
||||
"The label to be used next to the button",
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
/**
|
||||
* PikaResourceChooser:resource:
|
||||
*
|
||||
* The currently selected resource.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
resource_button_props[PROP_RESOURCE] =
|
||||
pika_param_spec_resource ("resource",
|
||||
"Resource",
|
||||
"The currently selected resource",
|
||||
TRUE, /* none_ok */
|
||||
PIKA_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class,
|
||||
N_PROPS, resource_button_props);
|
||||
|
||||
/**
|
||||
* PikaResourceChooser::resource-set:
|
||||
* @widget: the object which received the signal.
|
||||
* @resource: the currently selected resource.
|
||||
* @dialog_closing: whether the dialog was closed or not.
|
||||
*
|
||||
* The ::resource-set signal is emitted when the user selects a resource.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
resource_button_signals[RESOURCE_SET] =
|
||||
g_signal_new ("resource-set",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (PikaResourceChooserClass, resource_set),
|
||||
NULL, NULL,
|
||||
_pikaui_marshal_VOID__POINTER_BOOLEAN,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_OBJECT,
|
||||
G_TYPE_BOOLEAN);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_init (PikaResourceChooser *self)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (PIKA_RESOURCE_CHOOSER (self));
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (self),
|
||||
GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_box_set_spacing (GTK_BOX (self), 6);
|
||||
|
||||
priv->label_widget = gtk_label_new (NULL);
|
||||
gtk_box_pack_start (GTK_BOX (self), priv->label_widget, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_constructed (GObject *object)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (PIKA_RESOURCE_CHOOSER (object));
|
||||
gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->label_widget), priv->label);
|
||||
gtk_widget_show (GTK_WIDGET (priv->label_widget));
|
||||
|
||||
G_OBJECT_CLASS (pika_resource_chooser_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_dispose (GObject *self)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
PikaResourceChooserClass *klass;
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (PIKA_RESOURCE_CHOOSER (self));
|
||||
klass = PIKA_RESOURCE_CHOOSER_GET_CLASS (self);
|
||||
|
||||
if (priv->callback)
|
||||
{
|
||||
GType resource_type = klass->resource_type;
|
||||
|
||||
if (resource_type == PIKA_TYPE_FONT)
|
||||
pika_fonts_close_popup (priv->callback);
|
||||
else if (resource_type == PIKA_TYPE_GRADIENT)
|
||||
pika_gradients_close_popup (priv->callback);
|
||||
else if (resource_type == PIKA_TYPE_BRUSH)
|
||||
pika_brushes_close_popup (priv->callback);
|
||||
else if (resource_type == PIKA_TYPE_PALETTE)
|
||||
pika_palettes_close_popup (priv->callback);
|
||||
else if (resource_type == PIKA_TYPE_PATTERN)
|
||||
pika_patterns_close_popup (priv->callback);
|
||||
else
|
||||
g_warning ("%s: unhandled resource type", G_STRFUNC);
|
||||
|
||||
pika_plug_in_remove_temp_procedure (pika_get_plug_in (), priv->callback);
|
||||
g_clear_pointer (&priv->callback, g_free);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (pika_resource_chooser_parent_class)->dispose (self);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_finalize (GObject *object)
|
||||
{
|
||||
PikaResourceChooser *self = PIKA_RESOURCE_CHOOSER (object);
|
||||
PikaResourceChooserPrivate *priv = pika_resource_chooser_get_instance_private (self);
|
||||
|
||||
g_clear_pointer (&priv->title, g_free);
|
||||
g_clear_pointer (&priv->label, g_free);
|
||||
|
||||
G_OBJECT_CLASS (pika_resource_chooser_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_resource_chooser_set_drag_target:
|
||||
* @chooser: A [class@ResourceChooser]
|
||||
* @drag_region_widget: An interior widget to be a droppable region
|
||||
* and emit "drag-data-received" signal
|
||||
* @drag_target: The drag target to accept
|
||||
*
|
||||
* Called by a subclass init to specialize the instance.
|
||||
*
|
||||
* Subclass knows its interior widget whose region is a drop zone.
|
||||
* Subclass knows what things can be dropped (target.)
|
||||
* Self (super) handles the drop.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
pika_resource_chooser_set_drag_target (PikaResourceChooser *chooser,
|
||||
GtkWidget *drag_region_widget,
|
||||
const GtkTargetEntry *drag_target)
|
||||
{
|
||||
g_return_if_fail (PIKA_IS_RESOURCE_CHOOSER (chooser));
|
||||
g_return_if_fail (drag_target != NULL);
|
||||
g_return_if_fail (drag_region_widget != NULL);
|
||||
|
||||
gtk_drag_dest_set (drag_region_widget,
|
||||
GTK_DEST_DEFAULT_HIGHLIGHT |
|
||||
GTK_DEST_DEFAULT_MOTION |
|
||||
GTK_DEST_DEFAULT_DROP,
|
||||
drag_target, 1, /* Pass array of size 1 */
|
||||
GDK_ACTION_COPY);
|
||||
|
||||
/* connect drag_region_widget's drag_received signal to chooser's callback. */
|
||||
g_signal_connect_swapped (drag_region_widget, "drag-data-received",
|
||||
G_CALLBACK (pika_resource_select_drag_data_received),
|
||||
chooser);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_resource_chooser_set_clickable:
|
||||
* @chooser: A [class@ResourceChooser]
|
||||
* @widget: An interior widget that emits "clicked" signal
|
||||
*
|
||||
* Called by a subclass init to specialize the instance.
|
||||
*
|
||||
* Subclass knows its interior widget whose region when clicked
|
||||
* should popup remote chooser.
|
||||
* Self handles the click event.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
pika_resource_chooser_set_clickable (PikaResourceChooser *chooser,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
g_return_if_fail (PIKA_IS_RESOURCE_CHOOSER (chooser));
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
/* Require the widget have a signal "clicked", usually a button. */
|
||||
g_signal_connect_swapped (widget, "clicked",
|
||||
G_CALLBACK (pika_resource_chooser_clicked),
|
||||
chooser);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_resource_chooser_get_resource:
|
||||
* @chooser: A #PikaResourceChooser
|
||||
*
|
||||
* Gets the currently selected resource.
|
||||
*
|
||||
* Returns: (transfer none): an internal copy of the resource which must not be freed.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
PikaResource *
|
||||
pika_resource_chooser_get_resource (PikaResourceChooser *chooser)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (PIKA_IS_RESOURCE_CHOOSER (chooser), NULL);
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (chooser);
|
||||
|
||||
return priv->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_resource_chooser_set_resource:
|
||||
* @chooser: A #PikaResourceChooser
|
||||
* @resource: Resource to set.
|
||||
*
|
||||
* Sets the currently selected resource.
|
||||
* This will select the resource in both the button and any chooser popup.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
void
|
||||
pika_resource_chooser_set_resource (PikaResourceChooser *chooser,
|
||||
PikaResource *resource)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
|
||||
g_return_if_fail (PIKA_IS_RESOURCE_CHOOSER (chooser));
|
||||
g_return_if_fail (resource != NULL);
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (chooser);
|
||||
|
||||
if (priv->callback)
|
||||
{
|
||||
/* A popup chooser dialog is already shown.
|
||||
* Call its setter to change the selection there
|
||||
* (since all views of the resource must be consistent.)
|
||||
* That will call back, which will change our own view of the resource.
|
||||
*/
|
||||
pika_resource_chooser_set_remote_dialog (chooser, resource);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call our own setter. */
|
||||
pika_resource_chooser_callback (resource, FALSE, chooser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_resource_chooser_get_label:
|
||||
* @widget: A [class@ResourceChooser].
|
||||
*
|
||||
* Returns the label widget.
|
||||
*
|
||||
* Returns: (transfer none): the [class@Gtk.Widget] showing the label text.
|
||||
* Since: 3.0
|
||||
*/
|
||||
GtkWidget *
|
||||
pika_resource_chooser_get_label (PikaResourceChooser *widget)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (PIKA_IS_RESOURCE_CHOOSER (widget), NULL);
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (widget);
|
||||
return priv->label_widget;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
pika_resource_chooser_set_remote_dialog (PikaResourceChooser *self,
|
||||
PikaResource *resource)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv;
|
||||
PikaResourceChooserClass *klass;
|
||||
|
||||
g_return_if_fail (PIKA_IS_RESOURCE_CHOOSER (self));
|
||||
g_return_if_fail (resource != NULL);
|
||||
|
||||
priv = pika_resource_chooser_get_instance_private (self);
|
||||
klass = PIKA_RESOURCE_CHOOSER_GET_CLASS (self);
|
||||
|
||||
g_return_if_fail (klass->resource_type != G_TYPE_INVALID);
|
||||
g_return_if_fail (klass->resource_type == G_TYPE_FROM_INSTANCE (resource));
|
||||
|
||||
pika_resource_select_set (priv->callback, resource);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *gvalue,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaResourceChooser *self = PIKA_RESOURCE_CHOOSER (object);
|
||||
PikaResourceChooserPrivate *priv = pika_resource_chooser_get_instance_private (self);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
priv->title = g_value_dup_string (gvalue);
|
||||
break;
|
||||
|
||||
case PROP_LABEL:
|
||||
priv->label = g_value_dup_string (gvalue);
|
||||
break;
|
||||
|
||||
case PROP_RESOURCE:
|
||||
priv->resource = g_value_get_object (gvalue);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaResourceChooser *self = PIKA_RESOURCE_CHOOSER (object);
|
||||
PikaResourceChooserPrivate *priv = pika_resource_chooser_get_instance_private (self);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, priv->title);
|
||||
break;
|
||||
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, priv->label);
|
||||
break;
|
||||
|
||||
case PROP_RESOURCE:
|
||||
g_value_set_object (value, priv->resource);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* A callback from the remote resource select popup.
|
||||
* When user chooses a resource.
|
||||
* Via a temporary PDB procedure.
|
||||
*
|
||||
* Set self's model (priv->resource)
|
||||
* Notify any parent widget subscribed on the "resource" property
|
||||
* typically a prop widget.
|
||||
* Update the view, since model changed.
|
||||
*/
|
||||
static void
|
||||
pika_resource_chooser_callback (PikaResource *resource,
|
||||
gboolean dialog_closing,
|
||||
gpointer user_data)
|
||||
{
|
||||
PikaResourceChooser *self = PIKA_RESOURCE_CHOOSER (user_data);
|
||||
PikaResourceChooserPrivate *priv = pika_resource_chooser_get_instance_private (self);
|
||||
|
||||
priv->resource = resource;
|
||||
|
||||
PIKA_RESOURCE_CHOOSER_GET_CLASS (self)->draw_interior (self);
|
||||
|
||||
if (dialog_closing)
|
||||
g_clear_pointer (&priv->callback, g_free);
|
||||
|
||||
g_signal_emit (self, resource_button_signals[RESOURCE_SET], 0, resource, dialog_closing);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), resource_button_props[PROP_RESOURCE]);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_resource_chooser_clicked (PikaResourceChooser *self)
|
||||
{
|
||||
PikaResourceChooserPrivate *priv = pika_resource_chooser_get_instance_private (self);
|
||||
PikaResourceChooserClass *klass = PIKA_RESOURCE_CHOOSER_GET_CLASS (self);
|
||||
|
||||
if (priv->callback)
|
||||
{
|
||||
/* Popup already created. Calling setter raises the popup. */
|
||||
pika_resource_chooser_set_remote_dialog (self, priv->resource);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
|
||||
GBytes *handle = NULL;
|
||||
|
||||
if (PIKA_IS_DIALOG (toplevel))
|
||||
handle = pika_dialog_get_native_handle (PIKA_DIALOG (toplevel));
|
||||
|
||||
priv->callback = g_strdup (pika_resource_select_new (priv->title,
|
||||
handle,
|
||||
priv->resource,
|
||||
klass->resource_type,
|
||||
pika_resource_chooser_callback,
|
||||
self,
|
||||
NULL));
|
||||
pika_resource_chooser_set_remote_dialog (self, priv->resource);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Drag methods. */
|
||||
|
||||
static void
|
||||
pika_resource_select_drag_data_received (PikaResourceChooser *self,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData *selection,
|
||||
guint info,
|
||||
guint time)
|
||||
{
|
||||
gint length = gtk_selection_data_get_length (selection);
|
||||
gchar *str;
|
||||
|
||||
PikaResourceChooserClass *klass;
|
||||
|
||||
klass = PIKA_RESOURCE_CHOOSER_GET_CLASS (self);
|
||||
/* Require class resource_type was initialized. */
|
||||
g_assert (klass->resource_type != 0);
|
||||
|
||||
/* Drag data is a string that is the ID of the resource. */
|
||||
|
||||
if (gtk_selection_data_get_format (selection) != 8 || length < 1)
|
||||
{
|
||||
g_warning ("%s: received invalid resource data", G_STRFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
str = g_strndup ((const gchar *) gtk_selection_data_get_data (selection),
|
||||
length);
|
||||
|
||||
if (g_utf8_validate (str, -1, NULL))
|
||||
{
|
||||
gint pid;
|
||||
gpointer unused;
|
||||
gint name_offset = 0;
|
||||
|
||||
if (sscanf (str, "%i:%p:%n", &pid, &unused, &name_offset) >= 2 &&
|
||||
pid == pika_getpid () && name_offset > 0)
|
||||
{
|
||||
gchar *name = str + name_offset;
|
||||
PikaResource *resource;
|
||||
|
||||
resource = pika_resource_get_by_name (klass->resource_type, name);
|
||||
pika_resource_chooser_set_resource (self, resource);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (str);
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_UI_H_INSIDE__) && !defined (PIKA_COMPILATION)
|
||||
#error "Only <libpika/pikaui.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_RESOURCE_CHOOSER_H__
|
||||
#define __PIKA_RESOURCE_CHOOSER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_RESOURCE_CHOOSER (pika_resource_chooser_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (PikaResourceChooser, pika_resource_chooser, PIKA, RESOURCE_CHOOSER, GtkBox)
|
||||
|
||||
struct _PikaResourceChooserClass
|
||||
{
|
||||
GtkBoxClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (* resource_set) (PikaResourceChooser *chooser,
|
||||
PikaResource *resource,
|
||||
gboolean dialog_closing);
|
||||
|
||||
/* Abstract methods and class variables */
|
||||
void (*draw_interior) (PikaResourceChooser *chooser);
|
||||
|
||||
GType resource_type;
|
||||
|
||||
/* Padding for future expansion */
|
||||
gpointer padding[8];
|
||||
};
|
||||
|
||||
PikaResource * pika_resource_chooser_get_resource (PikaResourceChooser *chooser);
|
||||
void pika_resource_chooser_set_resource (PikaResourceChooser *chooser,
|
||||
PikaResource *resource);
|
||||
GtkWidget * pika_resource_chooser_get_label (PikaResourceChooser *widget);
|
||||
|
||||
|
||||
/* API from below, used by subclasses e.g. PikaBrushChooser */
|
||||
|
||||
void pika_resource_chooser_set_drag_target (PikaResourceChooser *chooser,
|
||||
GtkWidget *drag_region_widget,
|
||||
const GtkTargetEntry *drag_target);
|
||||
void pika_resource_chooser_set_clickable (PikaResourceChooser *chooser,
|
||||
GtkWidget *widget);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_RESOURCE_CHOOSER_H__ */
|
|
@ -0,0 +1,398 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikachoice.c
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "pikabasetypes.h"
|
||||
|
||||
#include "pikachoice.h"
|
||||
#include "pikaparamspecs.h"
|
||||
|
||||
|
||||
typedef struct _PikaChoiceDesc
|
||||
{
|
||||
gchar *label;
|
||||
gchar *help;
|
||||
gint id;
|
||||
gboolean sensitive;
|
||||
} PikaChoiceDesc;
|
||||
|
||||
enum
|
||||
{
|
||||
SENSITIVITY_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
struct _PikaChoice
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GHashTable *choices;
|
||||
GList *keys;
|
||||
};
|
||||
|
||||
|
||||
static void pika_choice_finalize (GObject *object);
|
||||
|
||||
static void pika_choice_desc_free (PikaChoiceDesc *desc);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (PikaChoice, pika_choice, G_TYPE_OBJECT)
|
||||
|
||||
#define parent_class pika_choice_parent_class
|
||||
|
||||
static guint pika_choice_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
pika_choice_class_init (PikaChoiceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
pika_choice_signals[SENSITIVITY_CHANGED] =
|
||||
g_signal_new ("sensitivity-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, /*G_STRUCT_OFFSET (PikaChoiceClass, sensitivity_changed),*/
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
object_class->finalize = pika_choice_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
pika_choice_init (PikaChoice *choice)
|
||||
{
|
||||
choice->choices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify) pika_choice_desc_free);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_choice_finalize (GObject *object)
|
||||
{
|
||||
PikaChoice *choice = PIKA_CHOICE (object);
|
||||
|
||||
g_hash_table_unref (choice->choices);
|
||||
g_list_free_full (choice->keys, (GDestroyNotify) g_free);
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
/**
|
||||
* pika_choice_new:
|
||||
*
|
||||
* Returns: (transfer full): a #PikaChoice.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
PikaChoice *
|
||||
pika_choice_new (void)
|
||||
{
|
||||
PikaChoice *choice;
|
||||
|
||||
choice = g_object_new (PIKA_TYPE_CHOICE, NULL);
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_new_with_values:
|
||||
* @nick: the first value.
|
||||
* @id: integer ID for @nick.
|
||||
* @label: the label of @nick.
|
||||
* @help: longer help text for @nick.
|
||||
* ...: more triplets of string to pre-fill the created %PikaChoice.
|
||||
*
|
||||
* Returns: (transfer full): a #PikaChoice.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
PikaChoice *
|
||||
pika_choice_new_with_values (const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help,
|
||||
...)
|
||||
{
|
||||
PikaChoice *choice;
|
||||
va_list va_args;
|
||||
|
||||
g_return_val_if_fail (nick != NULL, NULL);
|
||||
g_return_val_if_fail (label != NULL, NULL);
|
||||
|
||||
choice = pika_choice_new ();
|
||||
|
||||
va_start (va_args, help);
|
||||
|
||||
do
|
||||
{
|
||||
pika_choice_add (choice, nick, id, label, help);
|
||||
nick = va_arg (va_args, const gchar *);
|
||||
if (nick == NULL)
|
||||
break;
|
||||
id = va_arg (va_args, gint);
|
||||
label = va_arg (va_args, const gchar *);
|
||||
if (label == NULL)
|
||||
{
|
||||
g_critical ("%s: nick '%s' cannot have a NULL label.", G_STRFUNC, nick);
|
||||
break;
|
||||
}
|
||||
help = va_arg (va_args, const gchar *);
|
||||
}
|
||||
while (TRUE);
|
||||
|
||||
va_end (va_args);
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_add:
|
||||
* @choice: the %PikaChoice.
|
||||
* @nick: the nick of @choice.
|
||||
* @id: optional integer ID for @nick.
|
||||
* @label: the label of @choice.
|
||||
* @help: optional longer help text for @nick.
|
||||
*
|
||||
* This procedure adds a new possible value to @choice list of values.
|
||||
* The @id is an optional integer identifier. This can be useful for instance
|
||||
* when you want to work with different enum values mapped to each @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
pika_choice_add (PikaChoice *choice,
|
||||
const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
GList *duplicate;
|
||||
|
||||
g_return_if_fail (label != NULL);
|
||||
|
||||
desc = g_new0 (PikaChoiceDesc, 1);
|
||||
desc->id = id;
|
||||
desc->label = g_strdup (label);
|
||||
desc->help = help != NULL ? g_strdup (help) : NULL;
|
||||
desc->sensitive = TRUE;
|
||||
g_hash_table_insert (choice->choices, g_strdup (nick), desc);
|
||||
|
||||
duplicate = g_list_find_custom (choice->keys, nick, (GCompareFunc) g_strcmp0);
|
||||
if (duplicate != NULL)
|
||||
{
|
||||
choice->keys = g_list_remove_link (choice->keys, duplicate);
|
||||
pika_choice_desc_free (duplicate->data);
|
||||
g_list_free (duplicate);
|
||||
}
|
||||
choice->keys = g_list_append (choice->keys, g_strdup (nick));
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_is_valid:
|
||||
* @choice: a %PikaChoice.
|
||||
* @nick: the nick to check.
|
||||
*
|
||||
* This procedure checks if the given @nick is valid and refers to
|
||||
* an existing choice.
|
||||
*
|
||||
* Returns: Whether the choice is valid.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gboolean
|
||||
pika_choice_is_valid (PikaChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
|
||||
g_return_val_if_fail (PIKA_IS_CHOICE (choice), FALSE);
|
||||
g_return_val_if_fail (nick != NULL, FALSE);
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
return (desc != NULL && desc->sensitive);
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_list_nicks:
|
||||
* @choice: a %PikaChoice.
|
||||
* @nick: the nick to check.
|
||||
*
|
||||
* This procedure returns the list of nicks allowed for @choice.
|
||||
*
|
||||
* Returns: (element-type gchar*) (transfer none): The list of @choice's nicks.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GList *
|
||||
pika_choice_list_nicks (PikaChoice *choice)
|
||||
{
|
||||
/* I don't use g_hash_table_get_keys() on purpose, because I want to retain
|
||||
* the adding-time order.
|
||||
*/
|
||||
return choice->keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_get_id:
|
||||
* @choice: a %PikaChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Returns: the ID of @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gint
|
||||
pika_choice_get_id (PikaChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
return desc->id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_get_label:
|
||||
* @choice: a %PikaChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Returns: (transfer none): the label of @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
const gchar *
|
||||
pika_choice_get_label (PikaChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
return desc->label;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_get_help:
|
||||
* @choice: a %PikaChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Returns the longer documentation for @nick.
|
||||
*
|
||||
* Returns: (transfer none): the help text of @nick.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
const gchar *
|
||||
pika_choice_get_help (PikaChoice *choice,
|
||||
const gchar *nick)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
return desc->help;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_get_documentation:
|
||||
* @choice: the %PikaChoice.
|
||||
* @nick: the possible value's nick you need documentation for.
|
||||
* @label: (transfer none): the label of @nick.
|
||||
* @help: (transfer none): the help text of @nick.
|
||||
*
|
||||
* Returns the documentation strings for @nick.
|
||||
*
|
||||
* Returns: %TRUE if @nick is found, %FALSE otherwise.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
gboolean
|
||||
pika_choice_get_documentation (PikaChoice *choice,
|
||||
const gchar *nick,
|
||||
const gchar **label,
|
||||
const gchar **help)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
if (desc)
|
||||
{
|
||||
*label = desc->label;
|
||||
*help = desc->help;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_choice_set_sensitive:
|
||||
* @choice: the %PikaChoice.
|
||||
* @nick: the nick to lookup.
|
||||
*
|
||||
* Change the sensitivity of a possible @nick. Technically a non-sensitive @nick
|
||||
* means it cannot be chosen anymore (so [method@Gimp.Choice.is_valid] will
|
||||
* return %FALSE; nevertheless [method@Gimp.Choice.list_nicks] and other
|
||||
* functions to get information about a choice will still function).
|
||||
*
|
||||
* Returns: %TRUE if @nick is found, %FALSE otherwise.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
pika_choice_set_sensitive (PikaChoice *choice,
|
||||
const gchar *nick,
|
||||
gboolean sensitive)
|
||||
{
|
||||
PikaChoiceDesc *desc;
|
||||
|
||||
g_return_if_fail (PIKA_IS_CHOICE (choice));
|
||||
g_return_if_fail (nick != NULL);
|
||||
|
||||
desc = g_hash_table_lookup (choice->choices, nick);
|
||||
g_return_if_fail (desc != NULL);
|
||||
if (desc->sensitive != sensitive)
|
||||
{
|
||||
desc->sensitive = sensitive;
|
||||
g_signal_emit (choice, pika_choice_signals[SENSITIVITY_CHANGED], 0, nick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Private functions */
|
||||
|
||||
static void
|
||||
pika_choice_desc_free (PikaChoiceDesc *desc)
|
||||
{
|
||||
g_free (desc->label);
|
||||
g_free (desc->help);
|
||||
g_free (desc);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikachoice.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
|
||||
#error "Only <libpikabase/pikabase.h> can be included directly."
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __PIKA_CHOICE_H__
|
||||
#define __PIKA_CHOICE_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#define PIKA_TYPE_CHOICE (pika_choice_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (PikaChoice, pika_choice, PIKA, CHOICE, GObject)
|
||||
|
||||
|
||||
PikaChoice * pika_choice_new (void);
|
||||
PikaChoice * pika_choice_new_with_values (const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
void pika_choice_add (PikaChoice *choice,
|
||||
const gchar *nick,
|
||||
gint id,
|
||||
const gchar *label,
|
||||
const gchar *help);
|
||||
|
||||
gboolean pika_choice_is_valid (PikaChoice *choice,
|
||||
const gchar *nick);
|
||||
GList * pika_choice_list_nicks (PikaChoice *choice);
|
||||
gint pika_choice_get_id (PikaChoice *choice,
|
||||
const gchar *nick);
|
||||
const gchar * pika_choice_get_label (PikaChoice *choice,
|
||||
const gchar *nick);
|
||||
const gchar * pika_choice_get_help (PikaChoice *choice,
|
||||
const gchar *nick);
|
||||
gboolean pika_choice_get_documentation (PikaChoice *choice,
|
||||
const gchar *nick,
|
||||
const gchar **label,
|
||||
const gchar **help);
|
||||
|
||||
void pika_choice_set_sensitive (PikaChoice *choice,
|
||||
const gchar *nick,
|
||||
gboolean sensitive);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_CHOICE_H__ */
|
|
@ -0,0 +1,291 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikalabelstringwidget.c
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libpikacolor/pikacolor.h"
|
||||
#include "libpikamath/pikamath.h"
|
||||
#include "libpikabase/pikabase.h"
|
||||
|
||||
#include "pikalabelstringwidget.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: pikalabelstringwidget
|
||||
* @title: PikaLabelStringWidget
|
||||
* @short_description: Widget containing a label and a widget with a
|
||||
* string "value" property.
|
||||
*
|
||||
* This widget is a subclass of #PikaLabeled.
|
||||
**/
|
||||
|
||||
enum
|
||||
{
|
||||
VALUE_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_VALUE,
|
||||
PROP_WIDGET,
|
||||
};
|
||||
|
||||
typedef struct _PikaLabelStringWidgetPrivate
|
||||
{
|
||||
PikaLabeled parent_instance;
|
||||
|
||||
GtkWidget *widget;
|
||||
gchar *value;
|
||||
} PikaLabelStringWidgetPrivate;
|
||||
|
||||
static void pika_label_string_widget_constructed (GObject *object);
|
||||
static void pika_label_string_widget_finalize (GObject *object);
|
||||
static void pika_label_string_widget_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void pika_label_string_widget_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
static GtkWidget * pika_label_string_widget_populate (PikaLabeled *widget,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (PikaLabelStringWidget, pika_label_string_widget, PIKA_TYPE_LABELED)
|
||||
|
||||
#define parent_class pika_label_string_widget_parent_class
|
||||
|
||||
static guint pika_label_string_widget_signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static void
|
||||
pika_label_string_widget_class_init (PikaLabelStringWidgetClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
PikaLabeledClass *labeled_class = PIKA_LABELED_CLASS (klass);
|
||||
|
||||
pika_label_string_widget_signals[VALUE_CHANGED] =
|
||||
g_signal_new ("value-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (PikaLabelStringWidgetClass, value_changed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
object_class->constructed = pika_label_string_widget_constructed;
|
||||
object_class->finalize = pika_label_string_widget_finalize;
|
||||
object_class->set_property = pika_label_string_widget_set_property;
|
||||
object_class->get_property = pika_label_string_widget_get_property;
|
||||
|
||||
labeled_class->populate = pika_label_string_widget_populate;
|
||||
|
||||
/**
|
||||
* PikaLabelStringWidget:value:
|
||||
*
|
||||
* The currently set value.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
g_object_class_install_property (object_class, PROP_VALUE,
|
||||
g_param_spec_string ("value", NULL,
|
||||
"Current value",
|
||||
NULL,
|
||||
PIKA_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* PikaLabelStringWidget:widget:
|
||||
*
|
||||
* The widget holding a string property named "value".
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
g_object_class_install_property (object_class, PROP_WIDGET,
|
||||
g_param_spec_object ("widget", NULL,
|
||||
"String widget",
|
||||
GTK_TYPE_WIDGET,
|
||||
PIKA_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
pika_label_string_widget_init (PikaLabelStringWidget *widget)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
pika_label_string_widget_constructed (GObject *object)
|
||||
{
|
||||
PikaLabelStringWidget *widget = PIKA_LABEL_STRING_WIDGET (object);
|
||||
PikaLabelStringWidgetPrivate *priv = pika_label_string_widget_get_instance_private (widget);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
|
||||
|
||||
/* This is important to make this object into a property widget. It
|
||||
* will allow config object to bind the "value" property of this
|
||||
* widget, and therefore be updated automatically.
|
||||
*/
|
||||
g_object_bind_property (G_OBJECT (priv->widget), "value",
|
||||
object, "value",
|
||||
G_BINDING_BIDIRECTIONAL |
|
||||
G_BINDING_SYNC_CREATE);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_label_string_widget_finalize (GObject *object)
|
||||
{
|
||||
PikaLabelStringWidget *widget = PIKA_LABEL_STRING_WIDGET (object);
|
||||
PikaLabelStringWidgetPrivate *priv = pika_label_string_widget_get_instance_private (widget);
|
||||
|
||||
g_free (priv->value);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
pika_label_string_widget_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaLabelStringWidget *widget = PIKA_LABEL_STRING_WIDGET (object);
|
||||
PikaLabelStringWidgetPrivate *priv = pika_label_string_widget_get_instance_private (widget);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_VALUE:
|
||||
if (g_strcmp0 (priv->value, g_value_get_string (value)) != 0)
|
||||
{
|
||||
g_free (priv->value);
|
||||
priv->value = g_value_dup_string (value);
|
||||
g_signal_emit (object, pika_label_string_widget_signals[VALUE_CHANGED], 0);
|
||||
}
|
||||
break;
|
||||
case PROP_WIDGET:
|
||||
priv->widget = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pika_label_string_widget_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PikaLabelStringWidget *widget = PIKA_LABEL_STRING_WIDGET (object);
|
||||
PikaLabelStringWidgetPrivate *priv = pika_label_string_widget_get_instance_private (widget);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_VALUE:
|
||||
g_value_set_string (value, priv->value);
|
||||
break;
|
||||
case PROP_WIDGET:
|
||||
g_value_set_object (value, priv->widget);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
pika_label_string_widget_populate (PikaLabeled *labeled,
|
||||
gint *x,
|
||||
gint *y,
|
||||
gint *width,
|
||||
gint *height)
|
||||
{
|
||||
PikaLabelStringWidget *widget = PIKA_LABEL_STRING_WIDGET (labeled);
|
||||
PikaLabelStringWidgetPrivate *priv = pika_label_string_widget_get_instance_private (widget);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (widget), priv->widget, 1, 0, 1, 1);
|
||||
gtk_widget_show (priv->widget);
|
||||
|
||||
return priv->widget;
|
||||
}
|
||||
|
||||
/* Public Functions */
|
||||
|
||||
/**
|
||||
* pika_label_string_widget_new:
|
||||
* @text: The text for the #GtkLabel.
|
||||
* @widget: (transfer full): The #GtkWidget to use.
|
||||
*
|
||||
* Creates a new #PikaLabelStringWidget whose "value" property is bound to
|
||||
* that of @widget (which must therefore have such a string property).
|
||||
*
|
||||
* Returns: (transfer full): The new #PikaLabelStringWidget widget.
|
||||
**/
|
||||
GtkWidget *
|
||||
pika_label_string_widget_new (const gchar *text,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *string_widget;
|
||||
GParamSpec *pspec;
|
||||
|
||||
g_return_val_if_fail ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (widget),
|
||||
"value")) &&
|
||||
(G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_STRING ||
|
||||
G_PARAM_SPEC_TYPE (pspec) == PIKA_TYPE_PARAM_CHOICE),
|
||||
NULL);
|
||||
|
||||
string_widget = g_object_new (PIKA_TYPE_LABEL_STRING_WIDGET,
|
||||
"label", text,
|
||||
"widget", widget,
|
||||
NULL);
|
||||
|
||||
return string_widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* pika_label_string_widget_get_widget:
|
||||
* @widget: the #PikaLabelStringWidget.
|
||||
*
|
||||
* Returns: (transfer none): The new #GtkWidget packed next to the label.
|
||||
**/
|
||||
GtkWidget *
|
||||
pika_label_string_widget_get_widget (PikaLabelStringWidget *widget)
|
||||
{
|
||||
PikaLabelStringWidgetPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (PIKA_IS_LABEL_STRING_WIDGET (widget), NULL);
|
||||
|
||||
priv = pika_label_string_widget_get_instance_private (widget);
|
||||
|
||||
return priv->widget;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/* LIBPIKA - The PIKA Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* pikalabelstringwidget.h
|
||||
* Copyright (C) 2023 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__PIKA_WIDGETS_H_INSIDE__) && !defined (PIKA_WIDGETS_COMPILATION)
|
||||
#error "Only <libpikawidgets/pikawidgets.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __PIKA_LABEL_STRING_WIDGET_H__
|
||||
#define __PIKA_LABEL_STRING_WIDGET_H__
|
||||
|
||||
#include <libpikawidgets/pikalabeled.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define PIKA_TYPE_LABEL_STRING_WIDGET (pika_label_string_widget_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (PikaLabelStringWidget, pika_label_string_widget, PIKA, LABEL_STRING_WIDGET, PikaLabeled)
|
||||
|
||||
struct _PikaLabelStringWidgetClass
|
||||
{
|
||||
PikaLabeledClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (* value_changed) (GtkWidget *string_widget);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (* _pika_reserved1) (void);
|
||||
void (* _pika_reserved2) (void);
|
||||
void (* _pika_reserved3) (void);
|
||||
void (* _pika_reserved4) (void);
|
||||
void (* _pika_reserved5) (void);
|
||||
void (* _pika_reserved6) (void);
|
||||
void (* _pika_reserved7) (void);
|
||||
void (* _pika_reserved8) (void);
|
||||
};
|
||||
|
||||
GtkWidget * pika_label_string_widget_new (const gchar *text,
|
||||
GtkWidget *widget);
|
||||
|
||||
GtkWidget * pika_label_string_widget_get_widget (PikaLabelStringWidget *widget);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __PIKA_LABEL_STRING_WIDGET_H__ */
|
|
@ -0,0 +1,113 @@
|
|||
# PIKA - Photo and Image Kooker Application
|
||||
# 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/>.
|
||||
|
||||
sub drawables_popup {
|
||||
$blurb = 'Invokes the drawable selection dialog.';
|
||||
$help = 'Opens a dialog letting a user choose an drawable.';
|
||||
|
||||
&jehan_pdb_misc('2023');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'callback', type => 'string', non_empty => 1,
|
||||
desc => 'The callback PDB proc to call when user chooses an drawable' },
|
||||
{ name => 'popup_title', type => 'string',
|
||||
desc => 'Title of the drawable selection dialog' },
|
||||
{ name => 'drawable_type', type => 'string', non_empty => 1,
|
||||
desc => 'The name of the PIKA_TYPE_DRAWABLE subtype' },
|
||||
{ name => 'initial_drawable', type => 'drawable', null_ok => 1, no_validate => 1,
|
||||
desc => 'The drawable to set as the initial choice' },
|
||||
{ name => 'parent_window', type => 'bytes', null_ok => 1,
|
||||
desc => 'An optional parent window handle for the popup to be set transient to' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (pika->no_interface ||
|
||||
! pika_pdb_lookup_procedure (pika->pdb, callback) ||
|
||||
! pika_pdb_dialog_new (pika, context, progress,
|
||||
g_type_from_name (drawable_type),
|
||||
parent_window, popup_title, callback,
|
||||
PIKA_OBJECT (initial_drawable),
|
||||
NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub drawables_close_popup {
|
||||
$blurb = 'Close the drawable selection dialog.';
|
||||
$help = 'Closes an open drawable selection dialog.';
|
||||
|
||||
&jehan_pdb_misc('2023');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'callback', type => 'string', non_empty => 1,
|
||||
desc => 'The name of the callback registered for this pop-up' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (pika->no_interface ||
|
||||
! pika_pdb_lookup_procedure (pika->pdb, callback) ||
|
||||
! pika_pdb_dialog_close (pika, PIKA_TYPE_DRAWABLE, callback))
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub drawables_set_popup {
|
||||
$blurb = 'Sets the selected drawable in a drawable selection dialog.';
|
||||
$help = $blurb;
|
||||
|
||||
&jehan_pdb_misc('2023');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'callback', type => 'string', non_empty => 1,
|
||||
desc => 'The name of the callback registered for this pop-up' },
|
||||
{ name => 'drawable', type => 'drawable', no_validate => 1,
|
||||
desc => 'The drawable to set as selected' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (pika->no_interface ||
|
||||
! pika_pdb_lookup_procedure (pika->pdb, callback) ||
|
||||
! pika_pdb_dialog_set (pika, PIKA_TYPE_DRAWABLE, callback, PIKA_OBJECT (drawable), NULL))
|
||||
success = FALSE;
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
@headers = qw("core/pika.h"
|
||||
"core/pikadatafactory.h");
|
||||
|
||||
@procs = qw(drawables_popup
|
||||
drawables_close_popup
|
||||
drawables_set_popup);
|
||||
|
||||
%exports = (app => [@procs], lib => [@procs]);
|
||||
|
||||
$desc = 'Drawables UI';
|
||||
$doc_title = 'pikadrawableselect';
|
||||
$doc_short_desc = 'Methods of a drawable chooser dialog';
|
||||
|
||||
1;
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
|
||||
PERL="$1"
|
||||
top_srcdir="$2"
|
||||
top_builddir="$3"
|
||||
|
||||
# Environment for the pdbgen.pl file.
|
||||
destdir=`cd "$top_srcdir" && pwd`
|
||||
export destdir
|
||||
builddir=`cd "$top_builddir" && pwd`
|
||||
export BUILD builddir
|
||||
|
||||
cd "$top_srcdir"/
|
||||
$PERL -I "$top_builddir/pdb" -I "$top_srcdir/pdb" pdb/enumcode.pl
|
||||
RET=$?
|
||||
if [ $RET -eq 0 ]; then
|
||||
echo "/* Generated on `date`. */" > $top_builddir/pdb/stamp-enumcode.h
|
||||
fi
|
||||
exit $RET
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
PERL="$1"
|
||||
top_srcdir="$2"
|
||||
top_builddir="$3"
|
||||
|
||||
# Environment for the pdbgen.pl file.
|
||||
destdir=`cd "$top_srcdir" && pwd`
|
||||
export destdir
|
||||
builddir=`cd "$top_builddir" && pwd`
|
||||
export BUILD builddir
|
||||
|
||||
cd "$top_srcdir"/pdb
|
||||
shift 3
|
||||
$PERL enumgen.pl "${@}"
|
||||
RET=$?
|
||||
if [ $RET -eq 0 ]; then
|
||||
echo "/* Generated on `date`. */" > $top_builddir/pdb/stamp-enumgen.h
|
||||
fi
|
||||
exit $RET
|
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env pika-script-fu-interpreter-3.0
|
||||
|
||||
; A script that fails at query/registration time: ill-formed args in registration data
|
||||
|
||||
; Tests the fix for #6157
|
||||
|
||||
; Incomplete: FUTURE add more test cases.
|
||||
|
||||
; One script can't test all cases.
|
||||
; Several cases are tested here, but you must edit the script,
|
||||
; putting each case to the top: the failing top case stops interpretation.
|
||||
|
||||
; Install this script.
|
||||
; Start Gimp
|
||||
; Expect:
|
||||
; - an error in the stderr console, errors from SF re args
|
||||
; e.g. "adjustment default must be list"
|
||||
; - plugin should not install to the menus
|
||||
; - the interpreter must not crash !!!
|
||||
; - the procedure is not in ProcedureBrowser
|
||||
|
||||
; Note errors come before Pika Error Console is ready
|
||||
|
||||
; moot run func
|
||||
(define (script-fu-test-registration-fail ) ())
|
||||
|
||||
|
||||
; Case SF-ENUM not a list of two strings
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed arg spec: 1 is not a string
|
||||
SF-ENUM "foo" '("InterpolationType" 1)
|
||||
)
|
||||
|
||||
; This should be moot (since it should fail earlier.)
|
||||
; But leave this here so when it does succeed,
|
||||
; you know earlier test failed to fail.
|
||||
(script-fu-menu-register "script-fu-test-registration-fail"
|
||||
"<Image>/Test")
|
||||
|
||||
|
||||
|
||||
; More tests below.
|
||||
; Copy them to above, and retest.
|
||||
; Can't test them all at once.
|
||||
|
||||
|
||||
; Case SF-ADJUSTMENT default not a list
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed : 0 is not a list
|
||||
SF-ADJUSTMENT "foo" 0
|
||||
)
|
||||
|
||||
|
||||
; Case: SF-ADJUSTMENT wrong list length
|
||||
; At query time, SF throws error.
|
||||
; At query time, a critical from Pika re arg default not in range
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed arg spec: a list, but not proper length
|
||||
; Expect SF error
|
||||
SF-ADJUSTMENT "foo" '(0 )
|
||||
)
|
||||
|
||||
|
||||
|
||||
; Case SF-OPTIONS not a list
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed arg spec: a list, but not proper length
|
||||
SF-OPTION "foo" "bar"
|
||||
)
|
||||
|
||||
|
||||
; Case SF-OPTIONS default an empty list
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; semantics : empty list makes no sense
|
||||
SF-OPTION "foo" '()
|
||||
)
|
||||
|
||||
|
||||
; Case SF-OPTIONS list contains non-string
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; 1 is not a string
|
||||
SF-OPTION "foo" '("foo" 1)
|
||||
)
|
||||
|
||||
|
||||
|
||||
; Case SF-COLOR not a list or a string
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed arg spec: 1 is not a list or a string
|
||||
SF-COLOR "foo" 1 4 5
|
||||
)
|
||||
|
||||
; FUTURE more test cases for SF-COLOR
|
||||
|
||||
|
||||
; Case SF-ENUM not a list
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed arg spec: "bar" is not a list
|
||||
SF-ENUM "foo" "bar"
|
||||
)
|
||||
|
||||
; Case SF-ENUM not a list of two strings
|
||||
(script-fu-register "script-fu-test-registration-fail"
|
||||
"Moot" "Moot" "lkk" "lkk" "2023" "" ; requires no image
|
||||
|
||||
; ill-formed arg spec: 1 is not a string
|
||||
SF-ENUM "foo" '("InterpolationType" 1)
|
||||
)
|
||||
|
||||
; FUTURE more test cases for SF-ENUM
|
|
@ -0,0 +1,398 @@
|
|||
# Belarusian translation for pika.
|
||||
# Copyright (C) 2023 pika's COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the pika package.
|
||||
# Yuras Shumovich <shumovichy@gmail.com>, 2023.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: pika master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/pika/issues\n"
|
||||
"POT-Creation-Date: 2023-09-26 14:33+0000\n"
|
||||
"PO-Revision-Date: 2023-09-26 17:54+0300\n"
|
||||
"Last-Translator: Yuras Shumovich <shumovichy@gmail.com>\n"
|
||||
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
|
||||
"Language: be\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:7
|
||||
msgid "License Agreement"
|
||||
msgstr "Ліцэнзійнае пагадненне"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:10
|
||||
msgid "Setup built by Jernej Simonèiè, jernej-pika@ena.si"
|
||||
msgstr ""
|
||||
"Праграму ўсталявання сабраў Ерней Сімончыч (Jernej Simončič), jernej-"
|
||||
"pika@ena.si"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:13
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:16
|
||||
msgid "This version of PIKA requires Windows 7, or a newer version of Windows."
|
||||
msgstr ""
|
||||
"Гэтай версіі PIKA патрабуецца Windows 7 або любая пазнейшая версія Windows."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:23
|
||||
msgid "Development version"
|
||||
msgstr "Версія для распрацоўкі"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:28
|
||||
msgid ""
|
||||
"This is a development version of PIKA where some features may not be "
|
||||
"finished, or it may be unstable.%nThis version of PIKA is not intended for "
|
||||
"day-to-day work as it may be unstable, and you could lose your work.%nIf you "
|
||||
"encounter any problems, first verify that they haven't already been fixed in "
|
||||
"GIT before you contact the developers or report it in PIKA gitlab:%n_https://"
|
||||
"gitlab.gnome.org/GNOME/pika/issues%n%nDo you wish to continue with "
|
||||
"installation anyway?"
|
||||
msgstr ""
|
||||
"Гэта версія для распрацоўкі PIKA, некаторыя функцыі могуць быць "
|
||||
"незавершанымі або нестабільнымі.%nГэтая версія PIKA не прызначана для "
|
||||
"штодзённай працы, бо з-за нестабільнасці, вынікі працы могуць быць страчаны."
|
||||
"%nКалі вы сутыкнуліся з нейкімі праблемамі, спачатку трэба ўпэўніцца, што іх "
|
||||
"не выправілі на GIT і толькі пасля паведамляць аб праблемах распрацоўшчыкам "
|
||||
"PIKA на gitlab:%n_https://gitlab.gnome.org/GNOME/pika/issues%n%nУсё роўна "
|
||||
"працягваць усталяванне?"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:31
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:54
|
||||
msgid "&Continue"
|
||||
msgstr "&Працягнуць"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:34
|
||||
msgid "Exit"
|
||||
msgstr "Выйсці"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:44
|
||||
msgid ""
|
||||
"This version of PIKA requires a processor that supports SSE instructions."
|
||||
msgstr "Гэтай версіі PIKA патрабуецца працэсар з падтрымкай інструкцый SSE."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:48
|
||||
msgid "Display settings problem"
|
||||
msgstr "Праблема з наладамі дысплэя"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:51
|
||||
msgid ""
|
||||
"Setup has detected that your Windows is not running in 32 bits-per-pixel "
|
||||
"display mode. This has been known to cause stability problems with PIKA, so "
|
||||
"it's recommended to change the display colour depth to 32BPP before "
|
||||
"continuing."
|
||||
msgstr ""
|
||||
"Праграма ўсталявання выявіла, што ваша сістэма Windows запушчана не ў рэжыме "
|
||||
"адлюстравання 32bpp. вядома, што гэта можа выклікаць нестабільную працу "
|
||||
"PIKA, таму, перш чым працягваць, рэкамендуецца змяніць глыбіню колеру на "
|
||||
"32bpp."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:57
|
||||
msgid "E&xit"
|
||||
msgstr "&Выхад"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:61
|
||||
msgid ""
|
||||
"PIKA is now ready to be installed. Click the Install now button to install "
|
||||
"using the default settings, or click the Customize button if you'd like to "
|
||||
"have more control over what gets installed."
|
||||
msgstr ""
|
||||
"Цяпер PIKA гатовы да ўсталявання. Каб усталяваць праграму з прадвызначанымі "
|
||||
"наладамі, націсніце кнопку «Усталяваць», або націсніце «Наладзіць», каб "
|
||||
"выбраць пэўныя кампаненты."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:64
|
||||
msgid "&Install"
|
||||
msgstr "&Усталяваць"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:67
|
||||
msgid "&Customize"
|
||||
msgstr "&Наладзіць"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:72
|
||||
msgid "Compact installation"
|
||||
msgstr "Кампактнае ўсталяванне"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:76
|
||||
msgid "Custom installation"
|
||||
msgstr "Выбарачнае ўсталяванне"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:80
|
||||
msgid "Full installation"
|
||||
msgstr "Поўнае ўсталяванне"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:85
|
||||
msgid "Description"
|
||||
msgstr "Апісанне"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:89
|
||||
msgid "PIKA"
|
||||
msgstr "PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:93
|
||||
msgid "PIKA and all default plug-ins"
|
||||
msgstr "PIKA і ўсе прадвызначаныя ўбудовы"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:97
|
||||
msgid "Run-time libraries"
|
||||
msgstr "Бібліятэкі праграмы"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:101
|
||||
msgid "Run-time libraries used by PIKA, including GTK Run-time Environment"
|
||||
msgstr ""
|
||||
"Бібліятэкі, якія выкарыстоўвае PIKA, у тым ліку асяроддзе выканання GTK"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:105
|
||||
msgid "Debug symbols"
|
||||
msgstr "Адладачныя сімвалы"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:109
|
||||
msgid "Include information to help with debugging PIKA"
|
||||
msgstr "Уключыць інфармацыю, якая дапамагае з адладкай PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:113
|
||||
msgid "MS-Windows engine for GTK"
|
||||
msgstr "Рухавік MS Windows для GTK"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:117
|
||||
msgid "Native Windows look for PIKA"
|
||||
msgstr "Уласнасістэмны выгляд Windows для PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:121
|
||||
msgid "Support for old plug-ins"
|
||||
msgstr "Падтрымка старых убудоў"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:125
|
||||
msgid "Install libraries needed by old third-party plug-ins"
|
||||
msgstr "Усталяваць бібліятэкі, патрэбныя старым убудовам з пабочных крыніц"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:129
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:133
|
||||
msgid "Translations"
|
||||
msgstr "Пераклады"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:137
|
||||
msgid "Python scripting"
|
||||
msgstr "Скрыпты Python"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:141
|
||||
msgid "Allows you to use PIKA plugins written in Python scripting language."
|
||||
msgstr "Дазваляе выкарыстоўваць убудовы напісаныя на мове скрыптоў Python."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:145
|
||||
msgid "Lua scripting"
|
||||
msgstr "Скрыпты Lua"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:149
|
||||
msgid "Allows you to use PIKA plugins written in Lua scripting language."
|
||||
msgstr "Дазваляе выкарыстоўваць убудовы напісаныя на мове скрыптоў Lua."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:153
|
||||
msgid "MyPaint brushes"
|
||||
msgstr "Пэндзлі MyPaint"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:157
|
||||
msgid "Install the default set of MyPaint brushes"
|
||||
msgstr "Усталяваць прадвызначаны набор пэндзляў MyPaint"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:161
|
||||
msgid "PostScript support"
|
||||
msgstr "Падтрымка PostScript"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:165
|
||||
msgid "Allow PIKA to load PostScript files"
|
||||
msgstr "Дазваляе PIKA загружаць файлы PostScript"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:169
|
||||
msgid "Support for 32-bit plug-ins"
|
||||
msgstr "Падтрымка 32-бітных убудоў"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:173
|
||||
msgid ""
|
||||
"Include files necessary for using 32-bit plug-ins.%nRequired for Python "
|
||||
"support."
|
||||
msgstr ""
|
||||
"Уключыць файлы, неабходныя для выкарыстання 32-бітных плагінаў.%nПатрабуюцца "
|
||||
"для падтрымкі Python."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:178
|
||||
msgid "Additional icons:"
|
||||
msgstr "Дадатковыя значкі:"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:182
|
||||
msgid "Create a &desktop icon"
|
||||
msgstr "Стварыць значок на працоўным &стале"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:186
|
||||
msgid "Create a &Quick Launch icon"
|
||||
msgstr "Стварыць значок на &панэлі хуткага запуску"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:190
|
||||
msgid "Remove previous PIKA version"
|
||||
msgstr "Выдаліць папярэднюю версію PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:195
|
||||
msgid ""
|
||||
"There was a problem updating PIKA's environment in %1. If you get any errors "
|
||||
"loading the plug-ins, try uninstalling and re-installing PIKA."
|
||||
msgstr ""
|
||||
"Узнікла праблема падчас абнаўлення асяроддзя PIKA у %1. Калі вы атрымаеце "
|
||||
"памылкі падчас загрузкі ўбудоў, паспрабуйце выдаліць PIKA і потым зноў "
|
||||
"ўсталяваць."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:199
|
||||
msgid "Error extracting temporary data."
|
||||
msgstr "Памылка вымання часовых даных."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:203
|
||||
msgid "Error updating Python interpreter info."
|
||||
msgstr "Памылка абнаўлення інфармацыі пра інтэрпрэтатар Python."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:207
|
||||
msgid "Error updating MyPaint brushes info."
|
||||
msgstr "Памылка абнаўлення інфармацыі пра пэндзлі MyPaint."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:211
|
||||
msgid "There was an error updating %1."
|
||||
msgstr "Узнікла памылка падчас абнаўлення %1."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:215
|
||||
msgid "There was an error updating PIKA's configuration file %1."
|
||||
msgstr "Узнікла памылка падчас абнаўлення файла канфігурацыі PIKA %1."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:220
|
||||
msgid "Edit with PIKA"
|
||||
msgstr "Змяніць праз PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:225
|
||||
msgid "Select file associations"
|
||||
msgstr "Суаднясенне з файламі"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:229
|
||||
msgid "Extensions:"
|
||||
msgstr "Пашырэнні:"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:233
|
||||
msgid "Select the file types you wish to associate with PIKA"
|
||||
msgstr "Выберыце тыпы файлаў, якія вы хочаце суаднесці з PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:237
|
||||
msgid ""
|
||||
"This will make selected files open in PIKA when you double-click them in "
|
||||
"Explorer."
|
||||
msgstr ""
|
||||
"Такім чынам выбраныя файлы, пры падвойным націсканні ў Правадніку, будуць "
|
||||
"адкрывацца праз PIKA."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:241
|
||||
msgid "Select &All"
|
||||
msgstr "Вылучыць &усе"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:245
|
||||
msgid "Unselect &All"
|
||||
msgstr "Зняць вылучэнне з &усіх"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:249
|
||||
msgid "Select &Unused"
|
||||
msgstr "Вылучыць &нявыкарыстаныя"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:254
|
||||
msgid "File types to associate with PIKA:"
|
||||
msgstr "Тыпы файлаў, суаднесеныя PIKA:"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:258
|
||||
msgid "Removing previous version of PIKA:"
|
||||
msgstr "Выдаленне папярэдняй версіі PIKA:"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:262
|
||||
msgid ""
|
||||
"PIKA %1 cannot be installed over your currently installed PIKA version, and "
|
||||
"the automatic uninstall of old version has failed.%n%nPlease remove the "
|
||||
"previous version of PIKA yourself before installing this version in %2, or "
|
||||
"choose a Custom install, and select a different installation folder.%n%nThe "
|
||||
"Setup will now exit."
|
||||
msgstr ""
|
||||
"Немагчыма ўсталяваць PIKA %1 на ўсталяваную ў цяперашні час версію, і не "
|
||||
"ўдалося выдаліць старую версію аўтаматычна.%n%nПерш чым усталяваць у %2 "
|
||||
"гэтую версію PIKA, выдаліце ўручную папярэднюю, або націсніце кнопку "
|
||||
"«Наладзіць» і выберыце іншую папку ўсталявання.%n%nЗараз праграма "
|
||||
"ўсталявання завершыць працу."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:266
|
||||
msgid ""
|
||||
"PIKA %1 cannot be installed over your currently installed PIKA version, and "
|
||||
"Setup couldn't determine how to remove the old version automatically."
|
||||
"%n%nPlease remove the previous version of PIKA and any add-ons yourself "
|
||||
"before installing this version in %2, or choose a Custom install, and select "
|
||||
"a different installation folder.%n%nThe Setup will now exit."
|
||||
msgstr ""
|
||||
"Немагчыма ўсталяваць PIKA %1 на ўсталяваную ў цяперашні час версію, і "
|
||||
"праграма ўсталявання не можа вызначыць як выдаліць старую версію аўтаматычна."
|
||||
"%n%nПерш чым усталяваць у %2 гэтую версію PIKA, выдаліце ўручную папярэднюю "
|
||||
"версію і ўсе ўбудовы,, або націсніце кнопку «Наладзіць» і выберыце іншую "
|
||||
"папку ўсталявання.%n%nЗараз праграма ўсталявання завершыць працу."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:270
|
||||
msgid ""
|
||||
"Previous PIKA version was removed successfully, but Windows has to be "
|
||||
"restarted before the Setup can continue.%n%nAfter restarting your computer, "
|
||||
"Setup will continue next time an administrator logs in."
|
||||
msgstr ""
|
||||
"Папярэдняя версія PIKA паспяхова выдалена, але патрабуецца перазапусціць "
|
||||
"Windows, каб працягнуць ўсталяванне.%n%nПасля перазапуску камп'ютара, "
|
||||
"ўсталяванне працягнецца, калі адміністратар увойдзе ў сістэму."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:275
|
||||
msgid "There was an error restarting the Setup. (%1)"
|
||||
msgstr "Узнікла памылка падчас паўторнага запуску праграмы ўсталявання (%1)"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:279
|
||||
msgid "Cleaning up old files..."
|
||||
msgstr "Ачыстка старых файлаў..."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:284
|
||||
msgid "Remember: PIKA is Free Software.%n%nPlease visit"
|
||||
msgstr "Помніце, PIKA – свабоднае праграмнае забеспячэнне.%n%nНаведайце сайт"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:288
|
||||
msgid "for free updates."
|
||||
msgstr "дзеля бясплатных абнаўленняў."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:292
|
||||
msgid "Setting up file associations..."
|
||||
msgstr "Наладжваецца суаднясенне з тыпамі файлаў..."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:295
|
||||
msgid "Setting up environment for PIKA Python extension..."
|
||||
msgstr "Наладжваецца асяроддзе для ўбудоў PIKA, напісаных на Python..."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:298
|
||||
msgid "Setting up MyPaint brushes..."
|
||||
msgstr "Наладжваюцца пэндзлі MyPaint."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:301
|
||||
msgid "Setting up PIKA environment..."
|
||||
msgstr "Наладжваецца асяроддзе PIKA..."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:304
|
||||
msgid "Setting up PIKA configuration for 32-bit plug-in support..."
|
||||
msgstr "Наладжваецца канфігурацыя PIKA для падтрымкі 32-бітных убудоў..."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:309
|
||||
msgid "Launch PIKA"
|
||||
msgstr "Запусціць PIKA"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:314
|
||||
msgid "Removing add-on"
|
||||
msgstr "Выдаленне дадатковых кампанентаў"
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:318
|
||||
msgid "Internal error (%1)."
|
||||
msgstr "Унутраная памылка (%1)."
|
||||
|
||||
#: build/windows/installer/lang/setup.isl.xml.in:323
|
||||
msgid ""
|
||||
"PIKA does not appear to be installed in the selected directory. Continue "
|
||||
"anyway?"
|
||||
msgstr ""
|
||||
"Падобна, што PIKA не ўсталяваны ў выбраным каталогу. Усё роўна працягнуць?"
|
Loading…
Reference in New Issue