mirror of https://github.com/GNOME/gimp.git
app: add GimpToolWidgetGroup
GimpToolWidgetGroup is a tool widget acting as a container for child widgets, multiplexing widget events and demultiplexing tool events. It can be used by tools to display multiple widgets simultaneously. The group keeps track of the current focus widget, and hover widget. Certain events are only dispatched to/forwarded from these widgets. The hover widget is determined by performing a hit test for all the children, starting from the last child. The first widget returning GIMP_HIT_DIRECT, if any, is selected as the hover widget; otherwise, if the current focus widget returns GIMP_HIT_INDIRECT, it's selected; otherwise, if exactly one widget returns GIMP_HIT_INDIRECT, it's selected; otherwise, there is no hover widget. The focus widget is set when clicking on a widget (or programatically, using gimp_tool_widget_set_focus()). Additionally, the group can raise the clicked widget to the top of the stack (see gimp_tool_widget_group_set_auto_raise().)
This commit is contained in:
parent
614cdcc0a8
commit
4ef06b9922
|
@ -197,7 +197,9 @@ libappdisplay_a_sources = \
|
|||
gimptooltransformgrid.c \
|
||||
gimptooltransformgrid.h \
|
||||
gimptoolwidget.c \
|
||||
gimptoolwidget.h
|
||||
gimptoolwidget.h \
|
||||
gimptoolwidgetgroup.c \
|
||||
gimptoolwidgetgroup.h
|
||||
|
||||
libappdisplay_a_built_sources = display-enums.c
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ typedef struct _GimpStatusbar GimpStatusbar;
|
|||
typedef struct _GimpToolDialog GimpToolDialog;
|
||||
typedef struct _GimpToolGui GimpToolGui;
|
||||
typedef struct _GimpToolWidget GimpToolWidget;
|
||||
typedef struct _GimpToolWidgetGroup GimpToolWidgetGroup;
|
||||
|
||||
typedef struct _GimpDisplayXfer GimpDisplayXfer;
|
||||
typedef struct _Selection Selection;
|
||||
|
|
|
@ -0,0 +1,698 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimptoolwidgetgroup.c
|
||||
* Copyright (C) 2018 Ell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "display-types.h"
|
||||
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimplist.h"
|
||||
|
||||
#include "gimpcanvasgroup.h"
|
||||
#include "gimpdisplayshell.h"
|
||||
#include "gimptoolwidgetgroup.h"
|
||||
|
||||
|
||||
struct _GimpToolWidgetGroupPrivate
|
||||
{
|
||||
GimpContainer *children;
|
||||
|
||||
GimpToolWidget *focus_widget;
|
||||
GimpToolWidget *hover_widget;
|
||||
|
||||
gboolean auto_raise;
|
||||
};
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_tool_widget_group_finalize (GObject *object);
|
||||
|
||||
static void gimp_tool_widget_group_focus_changed (GimpToolWidget *widget);
|
||||
static gint gimp_tool_widget_group_button_press (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpButtonPressType press_type);
|
||||
static void gimp_tool_widget_group_button_release (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpButtonReleaseType release_type);
|
||||
static void gimp_tool_widget_group_motion (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state);
|
||||
static GimpHit gimp_tool_widget_group_hit (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
gboolean proximity);
|
||||
static void gimp_tool_widget_group_hover (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
gboolean proximity);
|
||||
static void gimp_tool_widget_group_leave_notify (GimpToolWidget *widget);
|
||||
static gboolean gimp_tool_widget_group_key_press (GimpToolWidget *widget,
|
||||
GdkEventKey *kevent);
|
||||
static gboolean gimp_tool_widget_group_key_release (GimpToolWidget *widget,
|
||||
GdkEventKey *kevent);
|
||||
static void gimp_tool_widget_group_motion_modifier (GimpToolWidget *widget,
|
||||
GdkModifierType key,
|
||||
gboolean press,
|
||||
GdkModifierType state);
|
||||
static void gimp_tool_widget_group_hover_modifier (GimpToolWidget *widget,
|
||||
GdkModifierType key,
|
||||
gboolean press,
|
||||
GdkModifierType state);
|
||||
static gboolean gimp_tool_widget_group_get_cursor (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpCursorType *cursor,
|
||||
GimpToolCursorType *tool_cursor,
|
||||
GimpCursorModifier *modifier);
|
||||
|
||||
static void gimp_tool_widget_group_children_add (GimpContainer *container,
|
||||
GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_children_remove (GimpContainer *container,
|
||||
GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_children_reorder (GimpContainer *container,
|
||||
GimpToolWidget *child,
|
||||
gint new_index,
|
||||
GimpToolWidgetGroup *group);
|
||||
|
||||
static void gimp_tool_widget_group_child_changed (GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_child_response (GimpToolWidget *child,
|
||||
gint response_id,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_child_snap_offsets (GimpToolWidget *child,
|
||||
gint offset_x,
|
||||
gint offset_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_child_status (GimpToolWidget *child,
|
||||
const gchar *status,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_child_status_coords (GimpToolWidget *child,
|
||||
const gchar *title,
|
||||
gdouble x,
|
||||
const gchar *separator,
|
||||
gdouble y,
|
||||
const gchar *help,
|
||||
GimpToolWidgetGroup *group);
|
||||
static void gimp_tool_widget_group_child_focus_changed (GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group);
|
||||
|
||||
static GimpToolWidget * gimp_tool_widget_group_get_hover_widget (GimpToolWidgetGroup *group,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
gboolean proximity,
|
||||
GimpHit *hit);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpToolWidgetGroup, gimp_tool_widget_group, GIMP_TYPE_TOOL_WIDGET)
|
||||
|
||||
#define parent_class gimp_tool_widget_group_parent_class
|
||||
|
||||
|
||||
/* priv functions */
|
||||
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_class_init (GimpToolWidgetGroupClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpToolWidgetClass *widget_class = GIMP_TOOL_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = gimp_tool_widget_group_finalize;
|
||||
|
||||
widget_class->focus_changed = gimp_tool_widget_group_focus_changed;
|
||||
widget_class->button_press = gimp_tool_widget_group_button_press;
|
||||
widget_class->button_release = gimp_tool_widget_group_button_release;
|
||||
widget_class->motion = gimp_tool_widget_group_motion;
|
||||
widget_class->hit = gimp_tool_widget_group_hit;
|
||||
widget_class->hover = gimp_tool_widget_group_hover;
|
||||
widget_class->leave_notify = gimp_tool_widget_group_leave_notify;
|
||||
widget_class->key_press = gimp_tool_widget_group_key_press;
|
||||
widget_class->key_release = gimp_tool_widget_group_key_release;
|
||||
widget_class->motion_modifier = gimp_tool_widget_group_motion_modifier;
|
||||
widget_class->hover_modifier = gimp_tool_widget_group_hover_modifier;
|
||||
widget_class->get_cursor = gimp_tool_widget_group_get_cursor;
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GimpToolWidgetGroupPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_init (GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv;
|
||||
|
||||
priv = group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
|
||||
GIMP_TYPE_TOOL_WIDGET_GROUP,
|
||||
GimpToolWidgetGroupPrivate);
|
||||
|
||||
priv->children = g_object_new (GIMP_TYPE_LIST,
|
||||
"children-type", GIMP_TYPE_TOOL_WIDGET,
|
||||
"append", TRUE,
|
||||
NULL);
|
||||
|
||||
g_signal_connect (priv->children, "add",
|
||||
G_CALLBACK (gimp_tool_widget_group_children_add),
|
||||
group);
|
||||
g_signal_connect (priv->children, "remove",
|
||||
G_CALLBACK (gimp_tool_widget_group_children_remove),
|
||||
group);
|
||||
g_signal_connect (priv->children, "reorder",
|
||||
G_CALLBACK (gimp_tool_widget_group_children_reorder),
|
||||
group);
|
||||
|
||||
gimp_container_add_handler (priv->children, "changed",
|
||||
G_CALLBACK (gimp_tool_widget_group_child_changed),
|
||||
group);
|
||||
gimp_container_add_handler (priv->children, "response",
|
||||
G_CALLBACK (gimp_tool_widget_group_child_response),
|
||||
group);
|
||||
gimp_container_add_handler (priv->children, "snap-offsets",
|
||||
G_CALLBACK (gimp_tool_widget_group_child_snap_offsets),
|
||||
group);
|
||||
gimp_container_add_handler (priv->children, "status",
|
||||
G_CALLBACK (gimp_tool_widget_group_child_status),
|
||||
group);
|
||||
gimp_container_add_handler (priv->children, "status-coords",
|
||||
G_CALLBACK (gimp_tool_widget_group_child_status_coords),
|
||||
group);
|
||||
gimp_container_add_handler (priv->children, "focus-changed",
|
||||
G_CALLBACK (gimp_tool_widget_group_child_focus_changed),
|
||||
group);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_finalize (GObject *object)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (object);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
g_clear_object (&priv->children);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_tool_widget_group_button_press (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpButtonPressType press_type)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->focus_widget != priv->hover_widget)
|
||||
{
|
||||
if (priv->hover_widget)
|
||||
gimp_tool_widget_set_focus (priv->hover_widget, TRUE);
|
||||
else if (priv->focus_widget)
|
||||
gimp_tool_widget_set_focus (priv->focus_widget, FALSE);
|
||||
}
|
||||
|
||||
if (priv->hover_widget)
|
||||
{
|
||||
if (priv->auto_raise)
|
||||
{
|
||||
gimp_container_reorder (priv->children,
|
||||
GIMP_OBJECT (priv->hover_widget), -1);
|
||||
}
|
||||
|
||||
return gimp_tool_widget_button_press (priv->hover_widget,
|
||||
coords, time, state, press_type);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_focus_changed (GimpToolWidget *widget)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->focus_widget)
|
||||
{
|
||||
GimpToolWidget *focus_widget = priv->focus_widget;
|
||||
|
||||
gimp_tool_widget_set_focus (priv->focus_widget,
|
||||
gimp_tool_widget_get_focus (widget));
|
||||
|
||||
priv->focus_widget = focus_widget;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_button_release (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state,
|
||||
GimpButtonReleaseType release_type)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->hover_widget)
|
||||
{
|
||||
gimp_tool_widget_button_release (priv->hover_widget,
|
||||
coords, time, state, release_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_motion (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
guint32 time,
|
||||
GdkModifierType state)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->hover_widget)
|
||||
gimp_tool_widget_motion (priv->hover_widget, coords, time, state);
|
||||
}
|
||||
|
||||
static GimpHit
|
||||
gimp_tool_widget_group_hit (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
gboolean proximity)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpHit hit;
|
||||
|
||||
gimp_tool_widget_group_get_hover_widget (group,
|
||||
coords, state, proximity,
|
||||
&hit);
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_hover (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
gboolean proximity)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *hover_widget;
|
||||
|
||||
hover_widget =
|
||||
gimp_tool_widget_group_get_hover_widget (group,
|
||||
coords, state, proximity,
|
||||
NULL);
|
||||
|
||||
if (priv->hover_widget && priv->hover_widget != hover_widget)
|
||||
gimp_tool_widget_leave_notify (priv->hover_widget);
|
||||
|
||||
priv->hover_widget = hover_widget;
|
||||
|
||||
if (priv->hover_widget)
|
||||
gimp_tool_widget_hover (priv->hover_widget, coords, state, proximity);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_leave_notify (GimpToolWidget *widget)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->hover_widget)
|
||||
{
|
||||
gimp_tool_widget_leave_notify (priv->hover_widget);
|
||||
|
||||
priv->hover_widget = NULL;
|
||||
}
|
||||
|
||||
GIMP_TOOL_WIDGET_CLASS (parent_class)->leave_notify (widget);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_tool_widget_group_key_press (GimpToolWidget *widget,
|
||||
GdkEventKey *kevent)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->focus_widget)
|
||||
return gimp_tool_widget_key_press (priv->focus_widget, kevent);
|
||||
|
||||
return GIMP_TOOL_WIDGET_CLASS (parent_class)->key_press (widget, kevent);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_tool_widget_group_key_release (GimpToolWidget *widget,
|
||||
GdkEventKey *kevent)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->focus_widget)
|
||||
return gimp_tool_widget_key_release (priv->focus_widget, kevent);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_motion_modifier (GimpToolWidget *widget,
|
||||
GdkModifierType key,
|
||||
gboolean press,
|
||||
GdkModifierType state)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->hover_widget)
|
||||
gimp_tool_widget_motion_modifier (priv->hover_widget, key, press, state);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_hover_modifier (GimpToolWidget *widget,
|
||||
GdkModifierType key,
|
||||
gboolean press,
|
||||
GdkModifierType state)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GList *iter;
|
||||
|
||||
for (iter = g_queue_peek_head_link (GIMP_LIST (priv->children)->queue);
|
||||
iter;
|
||||
iter = g_list_next (iter))
|
||||
{
|
||||
gimp_tool_widget_hover_modifier (iter->data, key, press, state);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_tool_widget_group_get_cursor (GimpToolWidget *widget,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
GimpCursorType *cursor,
|
||||
GimpToolCursorType *tool_cursor,
|
||||
GimpCursorModifier *modifier)
|
||||
{
|
||||
GimpToolWidgetGroup *group = GIMP_TOOL_WIDGET_GROUP (widget);
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
|
||||
if (priv->hover_widget)
|
||||
{
|
||||
return gimp_tool_widget_get_cursor (priv->hover_widget,
|
||||
coords, state,
|
||||
cursor, tool_cursor, modifier);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_children_add (GimpContainer *container,
|
||||
GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
GimpCanvasGroup *canvas_group;
|
||||
|
||||
canvas_group = GIMP_CANVAS_GROUP (gimp_tool_widget_get_item (widget));
|
||||
|
||||
gimp_canvas_group_add_item (canvas_group,
|
||||
gimp_tool_widget_get_item (child));
|
||||
|
||||
if (! priv->focus_widget)
|
||||
{
|
||||
priv->focus_widget = child;
|
||||
|
||||
gimp_tool_widget_set_focus (child, gimp_tool_widget_get_focus (widget));
|
||||
}
|
||||
|
||||
gimp_tool_widget_changed (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_children_remove (GimpContainer *container,
|
||||
GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
GimpCanvasGroup *canvas_group;
|
||||
|
||||
canvas_group = GIMP_CANVAS_GROUP (gimp_tool_widget_get_item (widget));
|
||||
|
||||
if (priv->focus_widget == child)
|
||||
{
|
||||
gimp_tool_widget_set_focus (child, FALSE);
|
||||
|
||||
priv->focus_widget = NULL;
|
||||
}
|
||||
|
||||
if (priv->hover_widget == child)
|
||||
{
|
||||
gimp_tool_widget_leave_notify (child);
|
||||
|
||||
priv->hover_widget = NULL;
|
||||
}
|
||||
|
||||
gimp_canvas_group_remove_item (canvas_group,
|
||||
gimp_tool_widget_get_item (child));
|
||||
|
||||
gimp_tool_widget_changed (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_children_reorder (GimpContainer *container,
|
||||
GimpToolWidget *child,
|
||||
gint new_index,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
GimpCanvasGroup *canvas_group;
|
||||
GList *iter;
|
||||
|
||||
canvas_group = GIMP_CANVAS_GROUP (gimp_tool_widget_get_item (widget));
|
||||
|
||||
for (iter = g_queue_peek_head_link (GIMP_LIST (container)->queue);
|
||||
iter;
|
||||
iter = g_list_next (iter))
|
||||
{
|
||||
GimpCanvasItem *item = gimp_tool_widget_get_item (iter->data);
|
||||
|
||||
gimp_canvas_group_remove_item (canvas_group, item);
|
||||
gimp_canvas_group_add_item (canvas_group, item);
|
||||
}
|
||||
|
||||
gimp_tool_widget_changed (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_child_changed (GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
|
||||
gimp_tool_widget_changed (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_child_response (GimpToolWidget *child,
|
||||
gint response_id,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
|
||||
if (priv->focus_widget == child)
|
||||
gimp_tool_widget_response (widget, response_id);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_child_snap_offsets (GimpToolWidget *child,
|
||||
gint offset_x,
|
||||
gint offset_y,
|
||||
gint width,
|
||||
gint height,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
|
||||
if (priv->hover_widget == child)
|
||||
{
|
||||
gimp_tool_widget_set_snap_offsets (widget,
|
||||
offset_x, offset_y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_child_status (GimpToolWidget *child,
|
||||
const gchar *status,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
|
||||
if (priv->hover_widget == child)
|
||||
gimp_tool_widget_set_status (widget, status);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_child_status_coords (GimpToolWidget *child,
|
||||
const gchar *title,
|
||||
gdouble x,
|
||||
const gchar *separator,
|
||||
gdouble y,
|
||||
const gchar *help,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
|
||||
if (priv->hover_widget == child)
|
||||
gimp_tool_widget_set_status_coords (widget, title, x, separator, y, help);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_tool_widget_group_child_focus_changed (GimpToolWidget *child,
|
||||
GimpToolWidgetGroup *group)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *widget = GIMP_TOOL_WIDGET (group);
|
||||
|
||||
if (gimp_tool_widget_get_focus (child))
|
||||
{
|
||||
if (priv->focus_widget && priv->focus_widget != child)
|
||||
gimp_tool_widget_set_focus (priv->focus_widget, FALSE);
|
||||
|
||||
priv->focus_widget = child;
|
||||
|
||||
gimp_tool_widget_set_focus (widget, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->focus_widget == child)
|
||||
priv->focus_widget = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GimpToolWidget *
|
||||
gimp_tool_widget_group_get_hover_widget (GimpToolWidgetGroup *group,
|
||||
const GimpCoords *coords,
|
||||
GdkModifierType state,
|
||||
gboolean proximity,
|
||||
GimpHit *hit)
|
||||
{
|
||||
GimpToolWidgetGroupPrivate *priv = group->priv;
|
||||
GimpToolWidget *indirect_child = NULL;
|
||||
gboolean indirect = FALSE;
|
||||
GList *iter;
|
||||
|
||||
for (iter = g_queue_peek_tail_link (GIMP_LIST (priv->children)->queue);
|
||||
iter;
|
||||
iter = g_list_previous (iter))
|
||||
{
|
||||
GimpToolWidget *child = iter->data;
|
||||
|
||||
switch (gimp_tool_widget_hit (child, coords, state, proximity))
|
||||
{
|
||||
case GIMP_HIT_DIRECT:
|
||||
if (hit) *hit = GIMP_HIT_DIRECT;
|
||||
|
||||
return child;
|
||||
|
||||
case GIMP_HIT_INDIRECT:
|
||||
if (! indirect || child == priv->focus_widget)
|
||||
indirect_child = child;
|
||||
else if (indirect_child != priv->focus_widget)
|
||||
indirect_child = NULL;
|
||||
|
||||
indirect = TRUE;
|
||||
|
||||
break;
|
||||
|
||||
case GIMP_HIT_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hit) *hit = indirect_child ? GIMP_HIT_INDIRECT : GIMP_HIT_NONE;
|
||||
|
||||
return indirect_child;
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
|
||||
GimpToolWidget *
|
||||
gimp_tool_widget_group_new (GimpDisplayShell *shell)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
|
||||
|
||||
return g_object_new (GIMP_TYPE_TOOL_WIDGET_GROUP,
|
||||
"shell", shell,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GimpContainer *
|
||||
gimp_tool_widget_group_get_children (GimpToolWidgetGroup *group)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_TOOL_WIDGET_GROUP (group), NULL);
|
||||
|
||||
return group->priv->children;
|
||||
}
|
||||
|
||||
GimpToolWidget *
|
||||
gimp_tool_widget_group_get_focus_widget (GimpToolWidgetGroup *group)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_TOOL_WIDGET_GROUP (group), NULL);
|
||||
|
||||
return group->priv->focus_widget;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_tool_widget_group_set_auto_raise (GimpToolWidgetGroup *group,
|
||||
gboolean auto_raise)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_TOOL_WIDGET_GROUP (group));
|
||||
|
||||
group->priv->auto_raise = auto_raise;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_tool_widget_group_get_auto_raise (GimpToolWidgetGroup *group)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_TOOL_WIDGET_GROUP (group), FALSE);
|
||||
|
||||
return group->priv->auto_raise;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimptoolwidgetgroup.h
|
||||
* Copyright (C) 2018 Ell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_TOOL_WIDGET_GROUP_H__
|
||||
#define __GIMP_TOOL_WIDGET_GROUP_H__
|
||||
|
||||
|
||||
#include "gimptoolwidget.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_TOOL_WIDGET_GROUP (gimp_tool_widget_group_get_type ())
|
||||
#define GIMP_TOOL_WIDGET_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_TOOL_WIDGET_GROUP, GimpToolWidgetGroup))
|
||||
#define GIMP_TOOL_WIDGET_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_TOOL_WIDGET_GROUP, GimpToolWidgetGroupClass))
|
||||
#define GIMP_IS_TOOL_WIDGET_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_TOOL_WIDGET_GROUP))
|
||||
#define GIMP_IS_TOOL_WIDGET_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_TOOL_WIDGET_GROUP))
|
||||
#define GIMP_TOOL_WIDGET_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_TOOL_WIDGET_GROUP, GimpToolWidgetGroupClass))
|
||||
|
||||
|
||||
typedef struct _GimpToolWidgetGroupPrivate GimpToolWidgetGroupPrivate;
|
||||
typedef struct _GimpToolWidgetGroupClass GimpToolWidgetGroupClass;
|
||||
|
||||
struct _GimpToolWidgetGroup
|
||||
{
|
||||
GimpToolWidget parent_instance;
|
||||
|
||||
GimpToolWidgetGroupPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GimpToolWidgetGroupClass
|
||||
{
|
||||
GimpToolWidgetClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gimp_tool_widget_group_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpToolWidget * gimp_tool_widget_group_new (GimpDisplayShell *shell);
|
||||
|
||||
GimpContainer * gimp_tool_widget_group_get_children (GimpToolWidgetGroup *group);
|
||||
|
||||
GimpToolWidget * gimp_tool_widget_group_get_focus_widget (GimpToolWidgetGroup *group);
|
||||
|
||||
void gimp_tool_widget_group_set_auto_raise (GimpToolWidgetGroup *group,
|
||||
gboolean auto_raise);
|
||||
gboolean gimp_tool_widget_group_get_auto_raise (GimpToolWidgetGroup *group);
|
||||
|
||||
|
||||
#endif /* __GIMP_TOOL_WIDGET_GROUP_H__ */
|
Loading…
Reference in New Issue