mirror of https://github.com/GNOME/gimp.git
libgimpwidgets: new GimpColorScaleEntry class.
Similarly to GimpScaleEntry, this is meant to replace usage of gimp_color_scale_entry_new() by having a proper widget. This is a child class of GimpScaleEntry which simply replaces the GtkScale by a GimpColorScale by adding a GimpScaleEntry class method to create the scale widget (only restriction: it must be a GtkRange subtype). This also triggers me to rename gimp_scale_entry_get_scale() into gimp_scale_entry_get_range() (as well as the 2 plug-ins already using this function).
This commit is contained in:
parent
4fe56cd388
commit
f27d172750
|
@ -17,6 +17,7 @@ libgimpwidgets_introspectable_headers = \
|
|||
../libgimpwidgets/gimpcolorprofilestore.h \
|
||||
../libgimpwidgets/gimpcolorprofileview.h \
|
||||
## ../libgimpwidgets/gimpcolorscale.h
|
||||
../libgimpwidgets/gimpcolorscaleentry.h \
|
||||
## ../libgimpwidgets/gimpcolorscales.h
|
||||
## ../libgimpwidgets/gimpcolorselect.h
|
||||
../libgimpwidgets/gimpcolorselection.h \
|
||||
|
@ -77,6 +78,7 @@ libgimpwidgets_introspectable = \
|
|||
../libgimpwidgets/gimpcolorprofilestore.c \
|
||||
../libgimpwidgets/gimpcolorprofileview.c \
|
||||
## ../libgimpwidgets/gimpcolorscale.c
|
||||
../libgimpwidgets/gimpcolorscaleentry.c \
|
||||
## ../libgimpwidgets/gimpcolorscales.c
|
||||
## ../libgimpwidgets/gimpcolorselect.c
|
||||
../libgimpwidgets/gimpcolorselection.c \
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpcolorscaleentry.c
|
||||
* Copyright (C) 2020 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 "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpmath/gimpmath.h"
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
|
||||
#include "gimpwidgets.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: gimpcolorscaleentry
|
||||
* @title: GimpColorScaleEntry
|
||||
* @short_description: Widget containing a color scale, a spin button
|
||||
* and a label.
|
||||
*
|
||||
* This widget is a subclass of #GimpScaleEntry showing a
|
||||
* #GimpColorScale instead of a #GtkScale.
|
||||
**/
|
||||
|
||||
|
||||
static GtkWidget * gimp_color_scale_entry_new_range_widget (GtkAdjustment *adjustment);
|
||||
|
||||
G_DEFINE_TYPE (GimpColorScaleEntry, gimp_color_scale_entry, GIMP_TYPE_SCALE_ENTRY)
|
||||
|
||||
#define parent_class gimp_color_scale_entry_parent_class
|
||||
|
||||
|
||||
static void
|
||||
gimp_color_scale_entry_class_init (GimpColorScaleEntryClass *klass)
|
||||
{
|
||||
GimpScaleEntryClass *entry_class = GIMP_SCALE_ENTRY_CLASS (klass);
|
||||
|
||||
entry_class->new_range_widget = gimp_color_scale_entry_new_range_widget;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_color_scale_entry_init (GimpColorScaleEntry *entry)
|
||||
{
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gimp_color_scale_entry_new_range_widget (GtkAdjustment *adjustment)
|
||||
{
|
||||
GtkWidget *scale;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL);
|
||||
|
||||
scale = gimp_color_scale_new (GTK_ORIENTATION_HORIZONTAL,
|
||||
GIMP_COLOR_SELECTOR_VALUE);
|
||||
|
||||
gtk_range_set_adjustment (GTK_RANGE (scale), adjustment);
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_color_scale_entry_new2:
|
||||
* @text: The text for the #GtkLabel.
|
||||
* @value: The initial value.
|
||||
* @lower: The lower boundary.
|
||||
* @upper: The upper boundary.
|
||||
* @digits: The number of decimal digits.
|
||||
*
|
||||
* Returns: (transfer full): The new #GimpColorScale widget.
|
||||
**/
|
||||
GtkWidget *
|
||||
gimp_color_scale_entry_new2 (const gchar *text,
|
||||
gdouble value,
|
||||
gdouble lower,
|
||||
gdouble upper,
|
||||
guint digits)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
|
||||
entry = g_object_new (GIMP_TYPE_COLOR_SCALE_ENTRY,
|
||||
"label", text,
|
||||
"value", value,
|
||||
"lower", lower,
|
||||
"upper", upper,
|
||||
"digits", digits,
|
||||
NULL);
|
||||
|
||||
return entry;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpcolorscaleentry.h
|
||||
* Copyright (C) 2020 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 (__GIMP_WIDGETS_H_INSIDE__) && !defined (GIMP_WIDGETS_COMPILATION)
|
||||
#error "Only <libgimpwidgets/gimpwidgets.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GIMP_COLOR_SCALE_ENTRY_H__
|
||||
#define __GIMP_COLOR_SCALE_ENTRY_H__
|
||||
|
||||
#include <libgimpwidgets/gimpscaleentry.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GIMP_TYPE_COLOR_SCALE_ENTRY (gimp_color_scale_entry_get_type ())
|
||||
#define GIMP_COLOR_SCALE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_COLOR_SCALE_ENTRY, GimpColorScaleEntry))
|
||||
#define GIMP_COLOR_SCALE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COLOR_SCALE_ENTRY, GimpColorScaleEntryClass))
|
||||
#define GIMP_IS_COLOR_SCALE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GIMP_TYPE_COLOR_SCALE_ENTRY))
|
||||
#define GIMP_IS_COLOR_SCALE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COLOR_SCALE_ENTRY))
|
||||
#define GIMP_COLOR_SCALE_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_COLOR_SCALE_ENTRY, GimpColorScaleEntryClass))
|
||||
|
||||
|
||||
typedef struct _GimpColorScaleEntryPrivate GimpColorScaleEntryPrivate;
|
||||
typedef struct _GimpColorScaleEntryClass GimpColorScaleEntryClass;
|
||||
|
||||
struct _GimpColorScaleEntry
|
||||
{
|
||||
GimpScaleEntry parent_instance;
|
||||
};
|
||||
|
||||
struct _GimpColorScaleEntryClass
|
||||
{
|
||||
GimpScaleEntryClass parent_class;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (* _gimp_reserved1) (void);
|
||||
void (* _gimp_reserved2) (void);
|
||||
void (* _gimp_reserved3) (void);
|
||||
void (* _gimp_reserved4) (void);
|
||||
void (* _gimp_reserved5) (void);
|
||||
void (* _gimp_reserved6) (void);
|
||||
void (* _gimp_reserved7) (void);
|
||||
void (* _gimp_reserved8) (void);
|
||||
};
|
||||
|
||||
GType gimp_color_scale_entry_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget * gimp_color_scale_entry_new2 (const gchar *text,
|
||||
gdouble value,
|
||||
gdouble lower,
|
||||
gdouble upper,
|
||||
guint digits);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_COLOR_SCALE_ENTRY_H__ */
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* gimpscaleentry.c
|
||||
* Copyright (C) 2000 Michael Natterer <mitch@gimp.org>
|
||||
* Copyright (C) 2020 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -128,7 +129,7 @@ gimp_scale_entry_class_init (GimpScaleEntryClass *klass)
|
|||
g_signal_new ("value-changed",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GimpSizeEntryClass, value_changed),
|
||||
G_STRUCT_OFFSET (GimpScaleEntryClass, value_changed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
|
@ -136,6 +137,8 @@ gimp_scale_entry_class_init (GimpScaleEntryClass *klass)
|
|||
object_class->set_property = gimp_scale_entry_set_property;
|
||||
object_class->get_property = gimp_scale_entry_get_property;
|
||||
|
||||
klass->new_range_widget = NULL;
|
||||
|
||||
/**
|
||||
* GimpScaleEntry:label:
|
||||
*
|
||||
|
@ -202,6 +205,7 @@ gimp_scale_entry_init (GimpScaleEntry *entry)
|
|||
static void
|
||||
gimp_scale_entry_constructed (GObject *object)
|
||||
{
|
||||
GimpScaleEntryClass *klass;
|
||||
GimpScaleEntry *entry = GIMP_SCALE_ENTRY (object);
|
||||
GtkAdjustment *spin_adjustment;
|
||||
GtkAdjustment *scale_adjustment;
|
||||
|
@ -225,8 +229,19 @@ gimp_scale_entry_constructed (GObject *object)
|
|||
/* Scale */
|
||||
scale_adjustment = gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 10.0, 0.0);
|
||||
|
||||
klass = GIMP_SCALE_ENTRY_GET_CLASS (entry);
|
||||
if (klass->new_range_widget)
|
||||
{
|
||||
entry->priv->scale = klass->new_range_widget (scale_adjustment);
|
||||
g_return_if_fail (GTK_IS_RANGE (entry->priv->scale));
|
||||
g_return_if_fail (scale_adjustment == gtk_range_get_adjustment (GTK_RANGE (entry->priv->scale)));
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->priv->scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, scale_adjustment);
|
||||
gtk_scale_set_draw_value (GTK_SCALE (entry->priv->scale), FALSE);
|
||||
}
|
||||
|
||||
gtk_widget_set_hexpand (entry->priv->scale, TRUE);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (entry), entry->priv->label, 0, 0, 1, 1);
|
||||
|
@ -338,8 +353,13 @@ gimp_scale_entry_set_property (GObject *object,
|
|||
{
|
||||
g_return_if_fail (entry->priv->scale && entry->priv->spinbutton);
|
||||
|
||||
if (GTK_IS_SCALE (entry->priv->scale))
|
||||
/* Subclasses may set this to any GtkRange, in particular it
|
||||
* may not be a subclass of GtkScale.
|
||||
*/
|
||||
gtk_scale_set_digits (GTK_SCALE (entry->priv->scale),
|
||||
g_value_get_uint (value));
|
||||
|
||||
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (entry->priv->spinbutton),
|
||||
g_value_get_uint (value));
|
||||
|
||||
|
@ -742,16 +762,20 @@ gimp_scale_entry_get_spin_button (GimpScaleEntry *entry)
|
|||
}
|
||||
|
||||
/**
|
||||
* gimp_scale_entry_get_scale:
|
||||
* gimp_scale_entry_get_range:
|
||||
* @entry: The #GtkScaleEntry.
|
||||
*
|
||||
* This function returns the #GtkScale packed in @entry. This can be
|
||||
* This function returns the #GtkRange packed in @entry. This can be
|
||||
* useful if you need to customize some aspects of the widget
|
||||
*
|
||||
* Returns: (transfer none): The #GtkScale contained in @entry.
|
||||
* By default, it is a #GtkScale, but it can be any other type of
|
||||
* #GtkRange if a subclass overrided the new_range_widget() protected
|
||||
* method.
|
||||
*
|
||||
* Returns: (transfer none): The #GtkRange contained in @entry.
|
||||
**/
|
||||
GtkWidget *
|
||||
gimp_scale_entry_get_scale (GimpScaleEntry *entry)
|
||||
gimp_scale_entry_get_range (GimpScaleEntry *entry)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_SCALE_ENTRY (entry), NULL);
|
||||
|
||||
|
@ -947,7 +971,7 @@ gimp_scale_entry_get_logarithmic (GimpScaleEntry *entry)
|
|||
* (which the widget cannot guess), you can call this function. If you
|
||||
* want even more modularity and have different increments on each
|
||||
* widget, use specific functions on gimp_scale_entry_get_spin_button()
|
||||
* and gimp_scale_entry_get_scale().
|
||||
* and gimp_scale_entry_get_range().
|
||||
*
|
||||
* Note that there is no `get` function because it could not return
|
||||
* shared values in case you edited each widget separately.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* gimpscaleentry.h
|
||||
* Copyright (C) 2000 Michael Natterer <mitch@gimp.org>,
|
||||
* 2008 Bill Skaggs <weskaggs@primate.ucdavis.edu>
|
||||
* 2020 Jehan
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -51,6 +52,12 @@ struct _GimpScaleEntryClass
|
|||
{
|
||||
GtkGridClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (* value_changed) (GimpScaleEntry *entry);
|
||||
|
||||
/* Class methods */
|
||||
GtkWidget * (* new_range_widget) (GtkAdjustment *adjustment);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (* _gimp_reserved1) (void);
|
||||
void (* _gimp_reserved2) (void);
|
||||
|
@ -76,7 +83,7 @@ gdouble gimp_scale_entry_get_value (GimpScaleEntry *entry);
|
|||
|
||||
GtkWidget * gimp_scale_entry_get_label (GimpScaleEntry *entry);
|
||||
GtkWidget * gimp_scale_entry_get_spin_button (GimpScaleEntry *entry);
|
||||
GtkWidget * gimp_scale_entry_get_scale (GimpScaleEntry *entry);
|
||||
GtkWidget * gimp_scale_entry_get_range (GimpScaleEntry *entry);
|
||||
|
||||
void gimp_scale_entry_set_range (GimpScaleEntry *entry,
|
||||
gdouble lower,
|
||||
|
|
|
@ -52,6 +52,8 @@ EXPORTS
|
|||
gimp_color_button_set_title
|
||||
gimp_color_button_set_type
|
||||
gimp_color_button_set_update
|
||||
gimp_color_scale_entry_get_type
|
||||
gimp_color_scale_entry_new2
|
||||
gimp_color_display_changed
|
||||
gimp_color_display_clone
|
||||
gimp_color_display_configure
|
||||
|
@ -365,7 +367,7 @@ EXPORTS
|
|||
gimp_ruler_set_unit
|
||||
gimp_scale_entry_get_label
|
||||
gimp_scale_entry_get_logarithmic
|
||||
gimp_scale_entry_get_scale
|
||||
gimp_scale_entry_get_range
|
||||
gimp_scale_entry_get_spin_button
|
||||
gimp_scale_entry_get_type
|
||||
gimp_scale_entry_get_value
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <libgimpwidgets/gimpcolorprofilestore.h>
|
||||
#include <libgimpwidgets/gimpcolorprofileview.h>
|
||||
#include <libgimpwidgets/gimpcolorscale.h>
|
||||
#include <libgimpwidgets/gimpcolorscaleentry.h>
|
||||
#include <libgimpwidgets/gimpcolorscales.h>
|
||||
#include <libgimpwidgets/gimpcolorselector.h>
|
||||
#include <libgimpwidgets/gimpcolorselect.h>
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef struct _GimpColorProfileComboBox GimpColorProfileComboBox;
|
|||
typedef struct _GimpColorProfileStore GimpColorProfileStore;
|
||||
typedef struct _GimpColorProfileView GimpColorProfileView;
|
||||
typedef struct _GimpColorScale GimpColorScale;
|
||||
typedef struct _GimpColorScaleEntry GimpColorScaleEntry;
|
||||
typedef struct _GimpColorScales GimpColorScales;
|
||||
typedef struct _GimpColorSelector GimpColorSelector;
|
||||
typedef struct _GimpColorSelect GimpColorSelect;
|
||||
|
|
|
@ -39,6 +39,7 @@ libgimpwidgets_sources_introspectable = files(
|
|||
'gimpcolorprofilecombobox.c',
|
||||
'gimpcolorprofilestore.c',
|
||||
'gimpcolorprofileview.c',
|
||||
'gimpcolorscaleentry.c',
|
||||
'gimpcolorselection.c',
|
||||
'gimpcolorselector.c',
|
||||
'gimpdialog.c',
|
||||
|
@ -111,6 +112,7 @@ libgimpwidgets_headers_introspectable = files(
|
|||
'gimpcolorprofilecombobox.h',
|
||||
'gimpcolorprofilestore.h',
|
||||
'gimpcolorprofileview.h',
|
||||
'gimpcolorscaleentry.h',
|
||||
'gimpcolorselection.h',
|
||||
'gimpcolorselector.h',
|
||||
'gimpdialog.h',
|
||||
|
|
|
@ -1226,7 +1226,7 @@ create_advanced_tab (GtkWidget *notebook)
|
|||
&filmvals.picture_space);
|
||||
gtk_grid_attach (GTK_GRID (grid), scale, 0, row++, 3, 1);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_label (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_scale (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_range (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_spin_button (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_show (scale);
|
||||
|
||||
|
@ -1265,7 +1265,7 @@ create_advanced_tab (GtkWidget *notebook)
|
|||
&filmvals.hole_space);
|
||||
gtk_grid_attach (GTK_GRID (grid), scale, 0, row++, 3, 1);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_label (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_scale (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_range (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_spin_button (GIMP_SCALE_ENTRY (scale)), 6);
|
||||
gtk_widget_show (scale);
|
||||
|
||||
|
|
|
@ -2888,7 +2888,7 @@ makewindow (void)
|
|||
scalezscale = gimp_scale_entry_new2 (_("Scale Z:"), 1.0, 0.0, 10.0, 2);
|
||||
gimp_scale_entry_set_increments (GIMP_SCALE_ENTRY (scalezscale), 0.1, 1.0);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_label (GIMP_SCALE_ENTRY (scalezscale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_scale(GIMP_SCALE_ENTRY (scalezscale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_range (GIMP_SCALE_ENTRY (scalezscale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_spin_button (GIMP_SCALE_ENTRY (scalezscale)), 6);
|
||||
g_signal_connect (scalezscale, "value-changed",
|
||||
G_CALLBACK (getscales),
|
||||
|
@ -2912,7 +2912,7 @@ makewindow (void)
|
|||
|
||||
rotzscale = gimp_scale_entry_new2 (_("Rotate Z:"), 0.0, 0.0, 360.0, 1);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_label (GIMP_SCALE_ENTRY (rotzscale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_scale (GIMP_SCALE_ENTRY (rotzscale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_range (GIMP_SCALE_ENTRY (rotzscale)), 6);
|
||||
gtk_widget_set_margin_bottom (gimp_scale_entry_get_spin_button (GIMP_SCALE_ENTRY (rotzscale)), 6);
|
||||
g_signal_connect (rotzscale, "value-changed",
|
||||
G_CALLBACK (getscales),
|
||||
|
|
Loading…
Reference in New Issue