2009-09-29 19:08:01 +00:00
|
|
|
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
2009-09-10 08:39:27 +00:00
|
|
|
/*
|
|
|
|
* st-entry.c: Plain entry actor
|
|
|
|
*
|
|
|
|
* Copyright 2008, 2009 Intel Corporation
|
2010-11-10 22:00:45 +00:00
|
|
|
* Copyright 2009, 2010 Red Hat, Inc.
|
|
|
|
* Copyright 2010 Florian Müllner
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms and conditions of the GNU Lesser General Public License,
|
|
|
|
* version 2.1, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope 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
|
2010-11-10 22:00:45 +00:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION:st-entry
|
|
|
|
* @short_description: Widget for displaying text
|
|
|
|
*
|
|
|
|
* #StEntry is a simple widget for displaying text. It derives from
|
|
|
|
* #StWidget to add extra style and placement functionality over
|
|
|
|
* #ClutterText. The internal #ClutterText is publicly accessibly to allow
|
|
|
|
* applications to set further properties.
|
|
|
|
*
|
|
|
|
* #StEntry supports the following pseudo style states:
|
2020-05-20 23:50:09 +00:00
|
|
|
*
|
|
|
|
* - `focus`: the widget has focus
|
|
|
|
* - `indeterminate`: the widget is showing the hint text or actor
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include <clutter/clutter.h>
|
|
|
|
|
|
|
|
#include "st-entry.h"
|
|
|
|
|
2011-10-17 20:01:58 +00:00
|
|
|
#include "st-icon.h"
|
2017-06-05 17:36:41 +00:00
|
|
|
#include "st-label.h"
|
2019-01-30 18:56:18 +00:00
|
|
|
#include "st-settings.h"
|
2009-09-10 08:39:27 +00:00
|
|
|
#include "st-widget.h"
|
|
|
|
#include "st-texture-cache.h"
|
|
|
|
#include "st-clipboard.h"
|
2010-06-10 12:15:02 +00:00
|
|
|
#include "st-private.h"
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2012-02-07 17:29:58 +00:00
|
|
|
#include "st-widget-accessible.h"
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
/* properties */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PROP_0,
|
|
|
|
|
2009-09-21 23:22:31 +00:00
|
|
|
PROP_CLUTTER_TEXT,
|
2017-06-05 17:43:27 +00:00
|
|
|
PROP_PRIMARY_ICON,
|
|
|
|
PROP_SECONDARY_ICON,
|
2009-09-21 23:22:31 +00:00
|
|
|
PROP_HINT_TEXT,
|
2017-06-05 17:36:41 +00:00
|
|
|
PROP_HINT_ACTOR,
|
2009-09-21 23:22:31 +00:00
|
|
|
PROP_TEXT,
|
2013-01-09 09:00:52 +00:00
|
|
|
PROP_INPUT_PURPOSE,
|
|
|
|
PROP_INPUT_HINTS,
|
2019-07-29 15:59:41 +00:00
|
|
|
|
|
|
|
N_PROPS
|
2009-09-10 08:39:27 +00:00
|
|
|
};
|
|
|
|
|
2019-07-29 15:59:41 +00:00
|
|
|
static GParamSpec *props[N_PROPS] = { NULL, };
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
/* signals */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PRIMARY_ICON_CLICKED,
|
|
|
|
SECONDARY_ICON_CLICKED,
|
|
|
|
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
#define ST_ENTRY_PRIV(x) st_entry_get_instance_private ((StEntry *) x)
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
typedef struct _StEntryPrivate StEntryPrivate;
|
2009-09-10 08:39:27 +00:00
|
|
|
struct _StEntryPrivate
|
|
|
|
{
|
|
|
|
ClutterActor *entry;
|
|
|
|
|
|
|
|
ClutterActor *primary_icon;
|
|
|
|
ClutterActor *secondary_icon;
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
ClutterActor *hint_actor;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
gfloat spacing;
|
2009-10-20 13:22:17 +00:00
|
|
|
|
2013-02-18 00:47:34 +00:00
|
|
|
gboolean has_ibeam;
|
2017-06-05 17:39:21 +00:00
|
|
|
|
2021-03-05 11:35:26 +00:00
|
|
|
StShadow *shadow_spec;
|
|
|
|
|
2018-11-24 11:37:19 +00:00
|
|
|
CoglPipeline *text_shadow_material;
|
2017-06-05 17:39:21 +00:00
|
|
|
gfloat shadow_width;
|
|
|
|
gfloat shadow_height;
|
2009-09-10 08:39:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static guint entry_signals[LAST_SIGNAL] = { 0, };
|
|
|
|
|
2015-09-24 16:04:48 +00:00
|
|
|
G_DEFINE_TYPE_WITH_PRIVATE (StEntry, st_entry, ST_TYPE_WIDGET);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2012-02-07 17:29:58 +00:00
|
|
|
static GType st_entry_accessible_get_type (void) G_GNUC_CONST;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
static void
|
|
|
|
st_entry_set_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
StEntry *entry = ST_ENTRY (gobject);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2017-06-05 17:43:27 +00:00
|
|
|
case PROP_PRIMARY_ICON:
|
|
|
|
st_entry_set_primary_icon (entry, g_value_get_object (value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_SECONDARY_ICON:
|
|
|
|
st_entry_set_secondary_icon (entry, g_value_get_object (value));
|
|
|
|
break;
|
|
|
|
|
2009-09-21 23:22:31 +00:00
|
|
|
case PROP_HINT_TEXT:
|
|
|
|
st_entry_set_hint_text (entry, g_value_get_string (value));
|
2009-09-10 08:39:27 +00:00
|
|
|
break;
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
case PROP_HINT_ACTOR:
|
|
|
|
st_entry_set_hint_actor (entry, g_value_get_object (value));
|
|
|
|
break;
|
|
|
|
|
2009-09-21 23:22:31 +00:00
|
|
|
case PROP_TEXT:
|
|
|
|
st_entry_set_text (entry, g_value_get_string (value));
|
2009-09-10 08:39:27 +00:00
|
|
|
break;
|
|
|
|
|
2013-01-09 09:00:52 +00:00
|
|
|
case PROP_INPUT_PURPOSE:
|
|
|
|
st_entry_set_input_purpose (entry, g_value_get_enum (value));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_INPUT_HINTS:
|
|
|
|
st_entry_set_input_hints (entry, g_value_get_flags (value));
|
|
|
|
break;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_get_property (GObject *gobject,
|
|
|
|
guint prop_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (gobject);
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
{
|
2009-09-21 23:22:31 +00:00
|
|
|
case PROP_CLUTTER_TEXT:
|
|
|
|
g_value_set_object (value, priv->entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
break;
|
|
|
|
|
2017-06-05 17:43:27 +00:00
|
|
|
case PROP_PRIMARY_ICON:
|
|
|
|
g_value_set_object (value, priv->primary_icon);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_SECONDARY_ICON:
|
|
|
|
g_value_set_object (value, priv->secondary_icon);
|
|
|
|
break;
|
|
|
|
|
2009-09-21 23:22:31 +00:00
|
|
|
case PROP_HINT_TEXT:
|
2017-06-05 17:36:41 +00:00
|
|
|
g_value_set_string (value, st_entry_get_hint_text (ST_ENTRY (gobject)));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_HINT_ACTOR:
|
|
|
|
g_value_set_object (value, priv->hint_actor);
|
2009-09-21 23:22:31 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_TEXT:
|
|
|
|
g_value_set_string (value, clutter_text_get_text (CLUTTER_TEXT (priv->entry)));
|
|
|
|
break;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2013-01-09 09:00:52 +00:00
|
|
|
case PROP_INPUT_PURPOSE:
|
2017-12-14 16:19:01 +00:00
|
|
|
g_value_set_enum (value, clutter_text_get_input_purpose (CLUTTER_TEXT (priv->entry)));
|
2013-01-09 09:00:52 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PROP_INPUT_HINTS:
|
2017-12-14 16:19:01 +00:00
|
|
|
g_value_set_flags (value, clutter_text_get_input_hints (CLUTTER_TEXT (priv->entry)));
|
2013-01-09 09:00:52 +00:00
|
|
|
break;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_dispose (GObject *object)
|
|
|
|
{
|
2011-10-17 20:01:58 +00:00
|
|
|
StEntry *entry = ST_ENTRY (object);
|
2017-06-05 17:39:21 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2018-11-24 11:37:19 +00:00
|
|
|
cogl_clear_object (&priv->text_shadow_material);
|
2017-06-05 17:39:21 +00:00
|
|
|
|
2010-03-10 23:22:06 +00:00
|
|
|
G_OBJECT_CLASS (st_entry_parent_class)->dispose (object);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-06-05 17:36:41 +00:00
|
|
|
st_entry_update_hint_visibility (StEntry *self)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
2017-06-05 17:36:41 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (self);
|
|
|
|
gboolean hint_visible =
|
|
|
|
priv->hint_actor != NULL &&
|
2020-03-11 11:32:07 +00:00
|
|
|
!clutter_text_has_preedit (CLUTTER_TEXT (priv->entry)) &&
|
2020-01-22 19:53:34 +00:00
|
|
|
strcmp (clutter_text_get_text (CLUTTER_TEXT (priv->entry)), "") == 0;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (priv->hint_actor)
|
|
|
|
g_object_set (priv->hint_actor, "visible", hint_visible, NULL);
|
2010-03-10 23:22:06 +00:00
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (hint_visible)
|
|
|
|
st_widget_add_style_pseudo_class (ST_WIDGET (self), "indeterminate");
|
|
|
|
else
|
|
|
|
st_widget_remove_style_pseudo_class (ST_WIDGET (self), "indeterminate");
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_style_changed (StWidget *self)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (self);
|
2009-09-20 01:10:15 +00:00
|
|
|
StThemeNode *theme_node;
|
2021-03-05 11:35:26 +00:00
|
|
|
StShadow *shadow_spec;
|
2009-09-20 01:10:15 +00:00
|
|
|
ClutterColor color;
|
2010-02-27 22:19:24 +00:00
|
|
|
gdouble size;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 01:10:15 +00:00
|
|
|
theme_node = st_widget_get_theme_node (self);
|
2018-03-26 11:38:57 +00:00
|
|
|
|
2021-03-05 11:35:26 +00:00
|
|
|
shadow_spec = st_theme_node_get_text_shadow (theme_node);
|
|
|
|
if (!priv->shadow_spec || !shadow_spec ||
|
|
|
|
!st_shadow_equal (shadow_spec, priv->shadow_spec))
|
|
|
|
{
|
|
|
|
g_clear_pointer (&priv->text_shadow_material, cogl_object_unref);
|
|
|
|
|
|
|
|
g_clear_pointer (&priv->shadow_spec, st_shadow_unref);
|
|
|
|
if (shadow_spec)
|
|
|
|
priv->shadow_spec = st_shadow_ref (shadow_spec);
|
|
|
|
}
|
|
|
|
|
2018-03-26 11:38:57 +00:00
|
|
|
_st_set_text_from_style (CLUTTER_TEXT (priv->entry), theme_node);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2011-07-09 08:41:32 +00:00
|
|
|
if (st_theme_node_lookup_length (theme_node, "caret-size", TRUE, &size))
|
2010-02-27 22:19:24 +00:00
|
|
|
clutter_text_set_cursor_size (CLUTTER_TEXT (priv->entry), (int)(.5 + size));
|
|
|
|
|
2011-07-09 08:41:32 +00:00
|
|
|
if (st_theme_node_lookup_color (theme_node, "caret-color", TRUE, &color))
|
2009-09-20 01:10:15 +00:00
|
|
|
clutter_text_set_cursor_color (CLUTTER_TEXT (priv->entry), &color);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2011-07-09 08:41:32 +00:00
|
|
|
if (st_theme_node_lookup_color (theme_node, "selection-background-color", TRUE, &color))
|
2009-09-20 01:10:15 +00:00
|
|
|
clutter_text_set_selection_color (CLUTTER_TEXT (priv->entry), &color);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2011-07-09 08:41:32 +00:00
|
|
|
if (st_theme_node_lookup_color (theme_node, "selected-color", TRUE, &color))
|
2011-03-02 21:18:42 +00:00
|
|
|
clutter_text_set_selected_text_color (CLUTTER_TEXT (priv->entry), &color);
|
|
|
|
|
2009-09-20 01:10:15 +00:00
|
|
|
ST_WIDGET_CLASS (st_entry_parent_class)->style_changed (self);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
2010-06-15 16:11:39 +00:00
|
|
|
static gboolean
|
|
|
|
st_entry_navigate_focus (StWidget *widget,
|
|
|
|
ClutterActor *from,
|
2018-11-27 12:58:25 +00:00
|
|
|
StDirectionType direction)
|
2010-06-15 16:11:39 +00:00
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (widget);
|
|
|
|
|
|
|
|
/* This is basically the same as st_widget_real_navigate_focus(),
|
|
|
|
* except that widget is behaving as a proxy for priv->entry (which
|
|
|
|
* isn't an StWidget and so has no can-focus flag of its own).
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (from == priv->entry)
|
|
|
|
return FALSE;
|
2012-09-06 20:12:44 +00:00
|
|
|
else if (st_widget_get_can_focus (widget) &&
|
2015-07-22 13:43:12 +00:00
|
|
|
clutter_actor_is_mapped (priv->entry))
|
2010-06-15 16:11:39 +00:00
|
|
|
{
|
|
|
|
clutter_actor_grab_key_focus (priv->entry);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
static void
|
|
|
|
st_entry_get_preferred_width (ClutterActor *actor,
|
|
|
|
gfloat for_height,
|
|
|
|
gfloat *min_width_p,
|
|
|
|
gfloat *natural_width_p)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
2009-09-20 17:41:13 +00:00
|
|
|
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
2020-04-08 22:05:20 +00:00
|
|
|
gfloat hint_w, hint_min_w, icon_w;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
st_theme_node_adjust_for_height (theme_node, &for_height);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
clutter_actor_get_preferred_width (priv->entry, for_height,
|
|
|
|
min_width_p,
|
|
|
|
natural_width_p);
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (priv->hint_actor)
|
|
|
|
{
|
2020-04-08 22:05:20 +00:00
|
|
|
clutter_actor_get_preferred_width (priv->hint_actor, -1,
|
|
|
|
&hint_min_w, &hint_w);
|
2017-06-05 17:36:41 +00:00
|
|
|
|
2020-04-08 22:05:20 +00:00
|
|
|
if (min_width_p && hint_min_w > *min_width_p)
|
|
|
|
*min_width_p = hint_min_w;
|
2017-06-05 17:36:41 +00:00
|
|
|
|
|
|
|
if (natural_width_p && hint_w > *natural_width_p)
|
|
|
|
*natural_width_p = hint_w;
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
if (priv->primary_icon)
|
|
|
|
{
|
|
|
|
clutter_actor_get_preferred_width (priv->primary_icon, -1, NULL, &icon_w);
|
|
|
|
|
|
|
|
if (min_width_p)
|
|
|
|
*min_width_p += icon_w + priv->spacing;
|
|
|
|
|
|
|
|
if (natural_width_p)
|
|
|
|
*natural_width_p += icon_w + priv->spacing;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->secondary_icon)
|
|
|
|
{
|
|
|
|
clutter_actor_get_preferred_width (priv->secondary_icon,
|
|
|
|
-1, NULL, &icon_w);
|
|
|
|
|
|
|
|
if (min_width_p)
|
|
|
|
*min_width_p += icon_w + priv->spacing;
|
|
|
|
|
|
|
|
if (natural_width_p)
|
|
|
|
*natural_width_p += icon_w + priv->spacing;
|
|
|
|
}
|
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
st_theme_node_adjust_preferred_width (theme_node, min_width_p, natural_width_p);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_get_preferred_height (ClutterActor *actor,
|
|
|
|
gfloat for_width,
|
|
|
|
gfloat *min_height_p,
|
|
|
|
gfloat *natural_height_p)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
2009-09-20 17:41:13 +00:00
|
|
|
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
2017-06-05 17:36:41 +00:00
|
|
|
gfloat hint_h, icon_h;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
st_theme_node_adjust_for_width (theme_node, &for_width);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
clutter_actor_get_preferred_height (priv->entry, for_width,
|
|
|
|
min_height_p,
|
|
|
|
natural_height_p);
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (priv->hint_actor)
|
|
|
|
{
|
|
|
|
clutter_actor_get_preferred_height (priv->hint_actor, -1, NULL, &hint_h);
|
|
|
|
|
|
|
|
if (min_height_p && hint_h > *min_height_p)
|
|
|
|
*min_height_p = hint_h;
|
|
|
|
|
|
|
|
if (natural_height_p && hint_h > *natural_height_p)
|
|
|
|
*natural_height_p = hint_h;
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
if (priv->primary_icon)
|
|
|
|
{
|
|
|
|
clutter_actor_get_preferred_height (priv->primary_icon,
|
|
|
|
-1, NULL, &icon_h);
|
|
|
|
|
|
|
|
if (min_height_p && icon_h > *min_height_p)
|
|
|
|
*min_height_p = icon_h;
|
|
|
|
|
|
|
|
if (natural_height_p && icon_h > *natural_height_p)
|
|
|
|
*natural_height_p = icon_h;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv->secondary_icon)
|
|
|
|
{
|
|
|
|
clutter_actor_get_preferred_height (priv->secondary_icon,
|
|
|
|
-1, NULL, &icon_h);
|
|
|
|
|
|
|
|
if (min_height_p && icon_h > *min_height_p)
|
|
|
|
*min_height_p = icon_h;
|
|
|
|
|
|
|
|
if (natural_height_p && icon_h > *natural_height_p)
|
|
|
|
*natural_height_p = icon_h;
|
|
|
|
}
|
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
st_theme_node_adjust_preferred_height (theme_node, min_height_p, natural_height_p);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_allocate (ClutterActor *actor,
|
2020-05-09 19:30:26 +00:00
|
|
|
const ClutterActorBox *box)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
2009-09-20 17:41:13 +00:00
|
|
|
StThemeNode *theme_node = st_widget_get_theme_node (ST_WIDGET (actor));
|
2017-06-05 17:36:41 +00:00
|
|
|
ClutterActorBox content_box, child_box, icon_box, hint_box;
|
2009-09-10 08:39:27 +00:00
|
|
|
gfloat icon_w, icon_h;
|
2020-04-08 22:05:20 +00:00
|
|
|
gfloat hint_w, hint_min_w, hint_h;
|
2009-09-10 08:39:27 +00:00
|
|
|
gfloat entry_h, min_h, pref_h, avail_h;
|
2013-08-26 22:24:26 +00:00
|
|
|
ClutterActor *left_icon, *right_icon;
|
2017-06-05 17:36:41 +00:00
|
|
|
gboolean is_rtl;
|
|
|
|
|
|
|
|
is_rtl = clutter_actor_get_text_direction (actor) == CLUTTER_TEXT_DIRECTION_RTL;
|
2013-08-26 22:24:26 +00:00
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (is_rtl)
|
2013-08-26 22:24:26 +00:00
|
|
|
{
|
|
|
|
right_icon = priv->primary_icon;
|
|
|
|
left_icon = priv->secondary_icon;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
left_icon = priv->primary_icon;
|
|
|
|
right_icon = priv->secondary_icon;
|
|
|
|
}
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2020-05-09 19:30:26 +00:00
|
|
|
clutter_actor_set_allocation (actor, box);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
st_theme_node_get_content_box (theme_node, box, &content_box);
|
|
|
|
|
|
|
|
avail_h = content_box.y2 - content_box.y1;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
child_box.x1 = content_box.x1;
|
|
|
|
child_box.x2 = content_box.x2;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2013-08-26 22:24:26 +00:00
|
|
|
if (left_icon)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
2013-08-26 22:24:26 +00:00
|
|
|
clutter_actor_get_preferred_width (left_icon, -1, NULL, &icon_w);
|
|
|
|
clutter_actor_get_preferred_height (left_icon, -1, NULL, &icon_h);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
icon_box.x1 = content_box.x1;
|
2009-09-10 08:39:27 +00:00
|
|
|
icon_box.x2 = icon_box.x1 + icon_w;
|
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
icon_box.y1 = (int) (content_box.y1 + avail_h / 2 - icon_h / 2);
|
2009-09-10 08:39:27 +00:00
|
|
|
icon_box.y2 = icon_box.y1 + icon_h;
|
|
|
|
|
2020-05-09 19:30:26 +00:00
|
|
|
clutter_actor_allocate (left_icon, &icon_box);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
/* reduce the size for the entry */
|
2017-06-07 00:56:17 +00:00
|
|
|
child_box.x1 = MIN (child_box.x2, child_box.x1 + icon_w + priv->spacing);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
2013-08-26 22:24:26 +00:00
|
|
|
if (right_icon)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
2013-08-26 22:24:26 +00:00
|
|
|
clutter_actor_get_preferred_width (right_icon, -1, NULL, &icon_w);
|
|
|
|
clutter_actor_get_preferred_height (right_icon, -1, NULL, &icon_h);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
icon_box.x2 = content_box.x2;
|
2009-09-10 08:39:27 +00:00
|
|
|
icon_box.x1 = icon_box.x2 - icon_w;
|
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
icon_box.y1 = (int) (content_box.y1 + avail_h / 2 - icon_h / 2);
|
2009-09-10 08:39:27 +00:00
|
|
|
icon_box.y2 = icon_box.y1 + icon_h;
|
|
|
|
|
2020-05-09 19:30:26 +00:00
|
|
|
clutter_actor_allocate (right_icon, &icon_box);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
/* reduce the size for the entry */
|
2017-06-07 00:56:17 +00:00
|
|
|
child_box.x2 = MAX (child_box.x1, child_box.x2 - icon_w - priv->spacing);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (priv->hint_actor)
|
|
|
|
{
|
|
|
|
/* now allocate the hint actor */
|
|
|
|
hint_box = child_box;
|
|
|
|
|
2020-04-08 22:05:20 +00:00
|
|
|
clutter_actor_get_preferred_width (priv->hint_actor, -1, &hint_min_w, &hint_w);
|
2017-06-05 17:36:41 +00:00
|
|
|
clutter_actor_get_preferred_height (priv->hint_actor, -1, NULL, &hint_h);
|
|
|
|
|
2020-04-08 22:05:20 +00:00
|
|
|
hint_w = CLAMP (hint_w, hint_min_w, child_box.x2 - child_box.x1);
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (is_rtl)
|
|
|
|
hint_box.x1 = hint_box.x2 - hint_w;
|
|
|
|
else
|
|
|
|
hint_box.x2 = hint_box.x1 + hint_w;
|
|
|
|
|
|
|
|
hint_box.y1 = ceil (content_box.y1 + avail_h / 2 - hint_h / 2);
|
|
|
|
hint_box.y2 = hint_box.y1 + hint_h;
|
|
|
|
|
2020-05-09 19:30:26 +00:00
|
|
|
clutter_actor_allocate (priv->hint_actor, &hint_box);
|
2017-06-05 17:36:41 +00:00
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
clutter_actor_get_preferred_height (priv->entry, child_box.x2 - child_box.x1,
|
|
|
|
&min_h, &pref_h);
|
|
|
|
|
|
|
|
entry_h = CLAMP (pref_h, min_h, avail_h);
|
|
|
|
|
2009-09-20 17:41:13 +00:00
|
|
|
child_box.y1 = (int) (content_box.y1 + avail_h / 2 - entry_h / 2);
|
2009-09-10 08:39:27 +00:00
|
|
|
child_box.y2 = child_box.y1 + entry_h;
|
|
|
|
|
2020-05-09 19:30:26 +00:00
|
|
|
clutter_actor_allocate (priv->entry, &child_box);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
2020-03-29 17:36:12 +00:00
|
|
|
static void
|
|
|
|
clutter_text_reactive_changed_cb (ClutterActor *text,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
ClutterActor *stage;
|
|
|
|
|
|
|
|
if (clutter_actor_get_reactive (text))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!clutter_actor_has_key_focus (text))
|
|
|
|
return;
|
|
|
|
|
|
|
|
stage = clutter_actor_get_stage (text);
|
|
|
|
if (stage == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
clutter_stage_set_key_focus (CLUTTER_STAGE (stage), NULL);
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
static void
|
|
|
|
clutter_text_focus_in_cb (ClutterText *text,
|
|
|
|
ClutterActor *actor)
|
|
|
|
{
|
2010-03-19 15:37:04 +00:00
|
|
|
st_widget_add_style_pseudo_class (ST_WIDGET (actor), "focus");
|
2009-09-10 08:39:27 +00:00
|
|
|
clutter_text_set_cursor_visible (text, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
clutter_text_focus_out_cb (ClutterText *text,
|
|
|
|
ClutterActor *actor)
|
|
|
|
{
|
2010-03-19 15:37:04 +00:00
|
|
|
st_widget_remove_style_pseudo_class (ST_WIDGET (actor), "focus");
|
2009-09-10 08:39:27 +00:00
|
|
|
clutter_text_set_cursor_visible (text, FALSE);
|
|
|
|
}
|
|
|
|
|
2020-03-11 11:32:07 +00:00
|
|
|
static void
|
|
|
|
clutter_text_cursor_changed (ClutterText *text,
|
|
|
|
StEntry *entry)
|
|
|
|
{
|
2021-03-05 10:31:26 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
|
|
|
|
|
2020-03-11 11:32:07 +00:00
|
|
|
st_entry_update_hint_visibility (entry);
|
2021-03-05 10:31:26 +00:00
|
|
|
|
|
|
|
g_clear_pointer (&priv->text_shadow_material, cogl_object_unref);
|
2020-03-11 11:32:07 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 17:39:21 +00:00
|
|
|
static void
|
|
|
|
clutter_text_changed_cb (GObject *object,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
StEntry *entry = ST_ENTRY (user_data);
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
|
|
|
|
|
2020-01-22 19:53:34 +00:00
|
|
|
st_entry_update_hint_visibility (entry);
|
|
|
|
|
2017-06-05 17:39:21 +00:00
|
|
|
/* Since the text changed, force a regen of the shadow texture */
|
2018-11-24 11:37:19 +00:00
|
|
|
cogl_clear_object (&priv->text_shadow_material);
|
2020-01-23 18:09:50 +00:00
|
|
|
|
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_TEXT]);
|
2017-06-05 17:39:21 +00:00
|
|
|
}
|
|
|
|
|
2021-03-05 11:17:07 +00:00
|
|
|
static void
|
|
|
|
invalidate_shadow_pipeline (GObject *object,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
StEntry *entry)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
|
|
|
|
|
|
|
|
g_clear_pointer (&priv->text_shadow_material, cogl_object_unref);
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
static void
|
|
|
|
st_entry_clipboard_callback (StClipboard *clipboard,
|
|
|
|
const gchar *text,
|
|
|
|
gpointer data)
|
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (data);
|
|
|
|
ClutterText *ctext = (ClutterText*)priv->entry;
|
2009-09-10 08:39:27 +00:00
|
|
|
gint cursor_pos;
|
|
|
|
|
|
|
|
if (!text)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* delete the current selection before pasting */
|
|
|
|
clutter_text_delete_selection (ctext);
|
|
|
|
|
|
|
|
/* "paste" the clipboard text into the entry */
|
|
|
|
cursor_pos = clutter_text_get_cursor_position (ctext);
|
|
|
|
clutter_text_insert_text (ctext, text, cursor_pos);
|
|
|
|
}
|
|
|
|
|
2011-11-09 16:40:13 +00:00
|
|
|
static gboolean
|
|
|
|
clutter_text_button_press_event (ClutterActor *actor,
|
|
|
|
ClutterButtonEvent *event,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
2016-02-23 02:46:00 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (user_data);
|
2011-11-09 16:40:13 +00:00
|
|
|
|
2019-01-30 18:56:18 +00:00
|
|
|
if (event->button == 2 &&
|
|
|
|
clutter_text_get_editable (CLUTTER_TEXT (priv->entry)))
|
2011-11-09 16:40:13 +00:00
|
|
|
{
|
2019-01-30 18:56:18 +00:00
|
|
|
StSettings *settings;
|
|
|
|
gboolean primary_paste_enabled;
|
|
|
|
|
|
|
|
settings = st_settings_get ();
|
|
|
|
g_object_get (settings, "primary-paste", &primary_paste_enabled, NULL);
|
|
|
|
|
|
|
|
if (primary_paste_enabled)
|
|
|
|
{
|
|
|
|
StClipboard *clipboard;
|
|
|
|
|
|
|
|
clipboard = st_clipboard_get_default ();
|
|
|
|
|
|
|
|
/* By the time the clipboard callback is called,
|
|
|
|
* the rest of the signal handlers will have
|
|
|
|
* run, making the text cursor to be in the correct
|
|
|
|
* place.
|
|
|
|
*/
|
|
|
|
st_clipboard_get_text (clipboard,
|
|
|
|
ST_CLIPBOARD_TYPE_PRIMARY,
|
|
|
|
st_entry_clipboard_callback,
|
|
|
|
user_data);
|
|
|
|
}
|
2011-11-09 16:40:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
static gboolean
|
|
|
|
st_entry_key_press_event (ClutterActor *actor,
|
|
|
|
ClutterKeyEvent *event)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
|
|
|
|
|
|
|
/* This is expected to handle events that were emitted for the inner
|
|
|
|
ClutterText. They only reach this function if the ClutterText
|
|
|
|
didn't handle them */
|
|
|
|
|
|
|
|
/* paste */
|
2014-04-26 18:00:43 +00:00
|
|
|
if (((event->modifier_state & CLUTTER_CONTROL_MASK)
|
|
|
|
&& event->keyval == CLUTTER_KEY_v) ||
|
2016-05-12 13:08:21 +00:00
|
|
|
((event->modifier_state & CLUTTER_CONTROL_MASK)
|
|
|
|
&& event->keyval == CLUTTER_KEY_V) ||
|
2014-04-26 18:00:43 +00:00
|
|
|
((event->modifier_state & CLUTTER_SHIFT_MASK)
|
|
|
|
&& event->keyval == CLUTTER_KEY_Insert))
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
|
|
|
StClipboard *clipboard;
|
|
|
|
|
|
|
|
clipboard = st_clipboard_get_default ();
|
|
|
|
|
2011-11-09 16:19:47 +00:00
|
|
|
st_clipboard_get_text (clipboard,
|
|
|
|
ST_CLIPBOARD_TYPE_CLIPBOARD,
|
|
|
|
st_entry_clipboard_callback,
|
|
|
|
actor);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy */
|
|
|
|
if ((event->modifier_state & CLUTTER_CONTROL_MASK)
|
2016-05-12 13:08:21 +00:00
|
|
|
&& (event->keyval == CLUTTER_KEY_c || event->keyval == CLUTTER_KEY_C) &&
|
2013-03-04 15:21:57 +00:00
|
|
|
clutter_text_get_password_char ((ClutterText*) priv->entry) == 0)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
|
|
|
StClipboard *clipboard;
|
|
|
|
gchar *text;
|
|
|
|
|
|
|
|
clipboard = st_clipboard_get_default ();
|
|
|
|
|
|
|
|
text = clutter_text_get_selection ((ClutterText*) priv->entry);
|
|
|
|
|
|
|
|
if (text && strlen (text))
|
2011-11-09 16:19:47 +00:00
|
|
|
st_clipboard_set_text (clipboard,
|
|
|
|
ST_CLIPBOARD_TYPE_CLIPBOARD,
|
|
|
|
text);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2020-06-07 22:42:00 +00:00
|
|
|
g_free (text);
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* cut */
|
|
|
|
if ((event->modifier_state & CLUTTER_CONTROL_MASK)
|
2016-05-12 13:08:21 +00:00
|
|
|
&& (event->keyval == CLUTTER_KEY_x || event->keyval == CLUTTER_KEY_X) &&
|
2013-03-04 15:21:57 +00:00
|
|
|
clutter_text_get_password_char ((ClutterText*) priv->entry) == 0)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
|
|
|
StClipboard *clipboard;
|
|
|
|
gchar *text;
|
|
|
|
|
|
|
|
clipboard = st_clipboard_get_default ();
|
|
|
|
|
|
|
|
text = clutter_text_get_selection ((ClutterText*) priv->entry);
|
|
|
|
|
|
|
|
if (text && strlen (text))
|
|
|
|
{
|
2011-11-09 16:19:47 +00:00
|
|
|
st_clipboard_set_text (clipboard,
|
|
|
|
ST_CLIPBOARD_TYPE_CLIPBOARD,
|
|
|
|
text);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
/* now delete the text */
|
|
|
|
clutter_text_delete_selection ((ClutterText *) priv->entry);
|
|
|
|
}
|
|
|
|
|
2020-06-07 22:42:00 +00:00
|
|
|
g_free (text);
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-09-26 14:43:17 +00:00
|
|
|
|
|
|
|
/* delete to beginning of line */
|
2016-05-12 13:08:21 +00:00
|
|
|
if ((event->modifier_state & CLUTTER_CONTROL_MASK) &&
|
|
|
|
(event->keyval == CLUTTER_KEY_u || event->keyval == CLUTTER_KEY_U))
|
2014-09-26 14:43:17 +00:00
|
|
|
{
|
|
|
|
int pos = clutter_text_get_cursor_position ((ClutterText *)priv->entry);
|
|
|
|
clutter_text_delete_text ((ClutterText *)priv->entry, 0, pos);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* delete to end of line */
|
2016-05-12 13:08:21 +00:00
|
|
|
if ((event->modifier_state & CLUTTER_CONTROL_MASK) &&
|
|
|
|
(event->keyval == CLUTTER_KEY_k || event->keyval == CLUTTER_KEY_K))
|
2014-09-26 14:43:17 +00:00
|
|
|
{
|
|
|
|
ClutterTextBuffer *buffer = clutter_text_get_buffer ((ClutterText *)priv->entry);
|
|
|
|
int pos = clutter_text_get_cursor_position ((ClutterText *)priv->entry);
|
|
|
|
clutter_text_buffer_delete_text (buffer, pos, -1);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-01-26 19:45:38 +00:00
|
|
|
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->key_press_event (actor, event);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_key_focus_in (ClutterActor *actor)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
|
|
|
|
|
|
|
/* We never want key focus. The ClutterText should be given first
|
|
|
|
pass for all key events */
|
|
|
|
clutter_actor_grab_key_focus (priv->entry);
|
|
|
|
}
|
|
|
|
|
2017-06-06 21:27:00 +00:00
|
|
|
static StEntryCursorFunc cursor_func = NULL;
|
|
|
|
static gpointer cursor_func_data = NULL;
|
2013-09-11 16:11:55 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_set_cursor_func: (skip)
|
|
|
|
*
|
|
|
|
* This function is for private use by libgnome-shell.
|
|
|
|
* Do not ever use.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
st_entry_set_cursor_func (StEntryCursorFunc func,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
cursor_func = func;
|
|
|
|
cursor_func_data = data;
|
|
|
|
}
|
|
|
|
|
2012-10-29 15:47:25 +00:00
|
|
|
static void
|
|
|
|
st_entry_set_cursor (StEntry *entry,
|
|
|
|
gboolean use_ibeam)
|
|
|
|
{
|
2017-06-06 21:27:18 +00:00
|
|
|
if (cursor_func)
|
|
|
|
cursor_func (entry, use_ibeam, cursor_func_data);
|
2013-02-18 00:47:34 +00:00
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
((StEntryPrivate *)ST_ENTRY_PRIV (entry))->has_ibeam = use_ibeam;
|
2012-10-29 15:47:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2013-11-15 16:08:29 +00:00
|
|
|
st_entry_enter_event (ClutterActor *actor,
|
|
|
|
ClutterCrossingEvent *event)
|
2012-10-29 15:47:25 +00:00
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
2022-02-25 15:11:54 +00:00
|
|
|
ClutterStage *stage;
|
|
|
|
ClutterActor *target;
|
|
|
|
|
|
|
|
stage = clutter_event_get_stage ((ClutterEvent *) event);
|
|
|
|
target = clutter_stage_get_event_actor (stage, (ClutterEvent *) event);
|
|
|
|
|
|
|
|
if (target == priv->entry && event->related != NULL)
|
2013-11-15 16:08:29 +00:00
|
|
|
st_entry_set_cursor (ST_ENTRY (actor), TRUE);
|
2012-10-29 15:47:25 +00:00
|
|
|
|
2013-11-15 16:08:29 +00:00
|
|
|
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->enter_event (actor, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
st_entry_leave_event (ClutterActor *actor,
|
|
|
|
ClutterCrossingEvent *event)
|
|
|
|
{
|
2022-02-25 15:11:54 +00:00
|
|
|
st_entry_set_cursor (ST_ENTRY (actor), FALSE);
|
2013-11-15 16:08:29 +00:00
|
|
|
|
|
|
|
return CLUTTER_ACTOR_CLASS (st_entry_parent_class)->leave_event (actor, event);
|
2012-10-29 15:47:25 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 17:39:21 +00:00
|
|
|
static void
|
2019-11-22 17:35:55 +00:00
|
|
|
st_entry_paint (ClutterActor *actor,
|
|
|
|
ClutterPaintContext *paint_context)
|
2017-06-05 17:39:21 +00:00
|
|
|
{
|
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
|
|
|
ClutterActorClass *parent_class;
|
|
|
|
|
2019-11-22 17:35:55 +00:00
|
|
|
st_widget_paint_background (ST_WIDGET (actor), paint_context);
|
2017-06-05 17:39:21 +00:00
|
|
|
|
2021-03-05 11:35:26 +00:00
|
|
|
if (priv->shadow_spec)
|
2017-06-05 17:39:21 +00:00
|
|
|
{
|
|
|
|
ClutterActorBox allocation;
|
|
|
|
float width, height;
|
|
|
|
|
|
|
|
clutter_actor_get_allocation_box (priv->entry, &allocation);
|
|
|
|
clutter_actor_box_get_size (&allocation, &width, &height);
|
|
|
|
|
2018-11-24 11:37:19 +00:00
|
|
|
if (priv->text_shadow_material == NULL ||
|
2017-06-05 17:39:21 +00:00
|
|
|
width != priv->shadow_width ||
|
|
|
|
height != priv->shadow_height)
|
|
|
|
{
|
2018-11-24 11:37:19 +00:00
|
|
|
CoglPipeline *material;
|
2017-06-05 17:39:21 +00:00
|
|
|
|
2018-11-24 11:37:19 +00:00
|
|
|
cogl_clear_object (&priv->text_shadow_material);
|
2017-06-05 17:39:21 +00:00
|
|
|
|
2021-03-05 11:35:26 +00:00
|
|
|
material = _st_create_shadow_pipeline_from_actor (priv->shadow_spec,
|
2017-06-05 17:39:21 +00:00
|
|
|
priv->entry);
|
|
|
|
|
|
|
|
priv->shadow_width = width;
|
|
|
|
priv->shadow_height = height;
|
|
|
|
priv->text_shadow_material = material;
|
|
|
|
}
|
|
|
|
|
2018-11-24 11:37:19 +00:00
|
|
|
if (priv->text_shadow_material != NULL)
|
2019-11-22 17:36:17 +00:00
|
|
|
{
|
|
|
|
CoglFramebuffer *framebuffer =
|
|
|
|
clutter_paint_context_get_framebuffer (paint_context);
|
|
|
|
|
2021-03-05 11:35:26 +00:00
|
|
|
_st_paint_shadow_with_opacity (priv->shadow_spec,
|
2019-11-22 17:36:17 +00:00
|
|
|
framebuffer,
|
|
|
|
priv->text_shadow_material,
|
|
|
|
&allocation,
|
|
|
|
clutter_actor_get_paint_opacity (priv->entry));
|
|
|
|
}
|
2017-06-05 17:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Since we paint the background ourselves, chain to the parent class
|
|
|
|
* of StWidget, to avoid painting it twice.
|
|
|
|
* This is needed as we still want to paint children.
|
|
|
|
*/
|
|
|
|
parent_class = g_type_class_peek_parent (st_entry_parent_class);
|
2019-11-22 17:35:55 +00:00
|
|
|
parent_class->paint (actor, paint_context);
|
2017-06-05 17:39:21 +00:00
|
|
|
}
|
|
|
|
|
2013-02-18 00:47:34 +00:00
|
|
|
static void
|
|
|
|
st_entry_unmap (ClutterActor *actor)
|
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (actor);
|
|
|
|
if (priv->has_ibeam)
|
2013-02-18 00:47:34 +00:00
|
|
|
st_entry_set_cursor (ST_ENTRY (actor), FALSE);
|
|
|
|
|
|
|
|
CLUTTER_ACTOR_CLASS (st_entry_parent_class)->unmap (actor);
|
|
|
|
}
|
|
|
|
|
2018-06-15 12:23:21 +00:00
|
|
|
static gboolean
|
|
|
|
st_entry_get_paint_volume (ClutterActor *actor,
|
|
|
|
ClutterPaintVolume *volume)
|
|
|
|
{
|
|
|
|
return clutter_paint_volume_set_from_allocation (volume, actor);
|
|
|
|
}
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
static void
|
|
|
|
st_entry_class_init (StEntryClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
2009-09-20 01:10:15 +00:00
|
|
|
StWidgetClass *widget_class = ST_WIDGET_CLASS (klass);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
gobject_class->set_property = st_entry_set_property;
|
|
|
|
gobject_class->get_property = st_entry_get_property;
|
|
|
|
gobject_class->dispose = st_entry_dispose;
|
|
|
|
|
|
|
|
actor_class->get_preferred_width = st_entry_get_preferred_width;
|
|
|
|
actor_class->get_preferred_height = st_entry_get_preferred_height;
|
|
|
|
actor_class->allocate = st_entry_allocate;
|
2017-06-05 17:39:21 +00:00
|
|
|
actor_class->paint = st_entry_paint;
|
2013-02-18 00:47:34 +00:00
|
|
|
actor_class->unmap = st_entry_unmap;
|
2018-06-15 12:23:21 +00:00
|
|
|
actor_class->get_paint_volume = st_entry_get_paint_volume;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
actor_class->key_press_event = st_entry_key_press_event;
|
|
|
|
actor_class->key_focus_in = st_entry_key_focus_in;
|
|
|
|
|
2013-11-15 16:08:29 +00:00
|
|
|
actor_class->enter_event = st_entry_enter_event;
|
|
|
|
actor_class->leave_event = st_entry_leave_event;
|
2012-10-29 15:47:25 +00:00
|
|
|
|
2009-09-20 01:10:15 +00:00
|
|
|
widget_class->style_changed = st_entry_style_changed;
|
2010-06-15 16:11:39 +00:00
|
|
|
widget_class->navigate_focus = st_entry_navigate_focus;
|
2012-02-07 17:29:58 +00:00
|
|
|
widget_class->get_accessible_type = st_entry_accessible_get_type;
|
2009-09-20 01:10:15 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:clutter-text:
|
|
|
|
*
|
|
|
|
* The internal #ClutterText actor supporting the #StEntry.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_CLUTTER_TEXT] =
|
|
|
|
g_param_spec_object ("clutter-text",
|
|
|
|
"Clutter Text",
|
|
|
|
"Internal ClutterText actor",
|
|
|
|
CLUTTER_TYPE_TEXT,
|
|
|
|
ST_PARAM_READABLE);
|
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:primary-icon:
|
|
|
|
*
|
|
|
|
* The #ClutterActor acting as the primary icon at the start of the #StEntry.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_PRIMARY_ICON] =
|
|
|
|
g_param_spec_object ("primary-icon",
|
|
|
|
"Primary Icon",
|
|
|
|
"Primary Icon actor",
|
|
|
|
CLUTTER_TYPE_ACTOR,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:secondary-icon:
|
|
|
|
*
|
|
|
|
* The #ClutterActor acting as the secondary icon at the end of the #StEntry.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_SECONDARY_ICON] =
|
|
|
|
g_param_spec_object ("secondary-icon",
|
|
|
|
"Secondary Icon",
|
|
|
|
"Secondary Icon actor",
|
|
|
|
CLUTTER_TYPE_ACTOR,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:hint-text:
|
|
|
|
*
|
|
|
|
* The text to display when the entry is empty and unfocused. Setting this
|
|
|
|
* will replace the actor of #StEntry::hint-actor.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_HINT_TEXT] =
|
|
|
|
g_param_spec_string ("hint-text",
|
|
|
|
"Hint Text",
|
|
|
|
"Text to display when the entry is not focused "
|
|
|
|
"and the text property is empty",
|
|
|
|
NULL,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:hint-actor:
|
|
|
|
*
|
|
|
|
* A #ClutterActor to display when the entry is empty and unfocused. Setting
|
|
|
|
* this will replace the actor displaying #StEntry:hint-text.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_HINT_ACTOR] =
|
|
|
|
g_param_spec_object ("hint-actor",
|
|
|
|
"Hint Actor",
|
|
|
|
"An actor to display when the entry is not focused "
|
|
|
|
"and the text property is empty",
|
|
|
|
CLUTTER_TYPE_ACTOR,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:text:
|
|
|
|
*
|
|
|
|
* The current text value of the #StEntry.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_TEXT] =
|
|
|
|
g_param_spec_string ("text",
|
|
|
|
"Text",
|
|
|
|
"Text of the entry",
|
|
|
|
NULL,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:input-purpose:
|
|
|
|
*
|
|
|
|
* The #ClutterInputContentPurpose that helps on-screen keyboards and similar
|
|
|
|
* input methods to decide which keys should be presented to the user.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_INPUT_PURPOSE] =
|
|
|
|
g_param_spec_enum ("input-purpose",
|
|
|
|
"Purpose",
|
|
|
|
"Purpose of the text field",
|
|
|
|
CLUTTER_TYPE_INPUT_CONTENT_PURPOSE,
|
|
|
|
CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
2020-05-20 23:50:09 +00:00
|
|
|
/**
|
|
|
|
* StEntry:input-hints:
|
|
|
|
*
|
|
|
|
* The #ClutterInputContentHintFlags providing additional hints (beyond
|
|
|
|
* #StEntry:input-purpose) that allow input methods to fine-tune their
|
|
|
|
* behaviour.
|
|
|
|
*/
|
2019-07-29 15:59:41 +00:00
|
|
|
props[PROP_INPUT_HINTS] =
|
|
|
|
g_param_spec_flags ("input-hints",
|
|
|
|
"hints",
|
|
|
|
"Hints for the text field behaviour",
|
|
|
|
CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS,
|
|
|
|
0,
|
2022-02-09 12:59:15 +00:00
|
|
|
ST_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
2019-07-29 15:59:41 +00:00
|
|
|
|
|
|
|
g_object_class_install_properties (gobject_class, N_PROPS, props);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
/* signals */
|
|
|
|
/**
|
|
|
|
* StEntry::primary-icon-clicked:
|
2013-10-09 17:31:26 +00:00
|
|
|
* @self: the #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Emitted when the primary icon is clicked.
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
entry_signals[PRIMARY_ICON_CLICKED] =
|
|
|
|
g_signal_new ("primary-icon-clicked",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
G_STRUCT_OFFSET (StEntryClass, primary_icon_clicked),
|
2011-10-18 22:17:49 +00:00
|
|
|
NULL, NULL, NULL,
|
2009-09-10 08:39:27 +00:00
|
|
|
G_TYPE_NONE, 0);
|
2020-05-20 23:50:09 +00:00
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
/**
|
|
|
|
* StEntry::secondary-icon-clicked:
|
2013-10-09 17:31:26 +00:00
|
|
|
* @self: the #StEntry
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Emitted when the secondary icon is clicked.
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
entry_signals[SECONDARY_ICON_CLICKED] =
|
|
|
|
g_signal_new ("secondary-icon-clicked",
|
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
G_STRUCT_OFFSET (StEntryClass, secondary_icon_clicked),
|
2011-10-18 22:17:49 +00:00
|
|
|
NULL, NULL, NULL,
|
2009-09-10 08:39:27 +00:00
|
|
|
G_TYPE_NONE, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_init (StEntry *entry)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2017-12-14 16:19:01 +00:00
|
|
|
priv->entry = g_object_new (CLUTTER_TYPE_TEXT,
|
2009-09-10 08:39:27 +00:00
|
|
|
"line-alignment", PANGO_ALIGN_LEFT,
|
|
|
|
"editable", TRUE,
|
|
|
|
"reactive", TRUE,
|
|
|
|
"single-line-mode", TRUE,
|
|
|
|
NULL);
|
|
|
|
|
2020-03-18 21:10:36 +00:00
|
|
|
g_object_bind_property (G_OBJECT (entry), "reactive",
|
|
|
|
priv->entry, "reactive",
|
|
|
|
G_BINDING_DEFAULT);
|
|
|
|
|
2020-03-29 17:36:12 +00:00
|
|
|
g_signal_connect(priv->entry, "notify::reactive",
|
|
|
|
G_CALLBACK (clutter_text_reactive_changed_cb), entry);
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
g_signal_connect (priv->entry, "key-focus-in",
|
|
|
|
G_CALLBACK (clutter_text_focus_in_cb), entry);
|
|
|
|
|
|
|
|
g_signal_connect (priv->entry, "key-focus-out",
|
|
|
|
G_CALLBACK (clutter_text_focus_out_cb), entry);
|
|
|
|
|
2011-11-09 16:40:13 +00:00
|
|
|
g_signal_connect (priv->entry, "button-press-event",
|
|
|
|
G_CALLBACK (clutter_text_button_press_event), entry);
|
|
|
|
|
2020-03-11 11:32:07 +00:00
|
|
|
g_signal_connect (priv->entry, "cursor-changed",
|
|
|
|
G_CALLBACK (clutter_text_cursor_changed), entry);
|
|
|
|
|
2017-06-05 17:39:21 +00:00
|
|
|
g_signal_connect (priv->entry, "notify::text",
|
|
|
|
G_CALLBACK (clutter_text_changed_cb), entry);
|
|
|
|
|
2021-03-05 11:17:07 +00:00
|
|
|
/* These properties might get set from CSS using _st_set_text_from_style */
|
|
|
|
g_signal_connect (priv->entry, "notify::font-description",
|
|
|
|
G_CALLBACK (invalidate_shadow_pipeline), entry);
|
|
|
|
|
|
|
|
g_signal_connect (priv->entry, "notify::attributes",
|
|
|
|
G_CALLBACK (invalidate_shadow_pipeline), entry);
|
|
|
|
|
|
|
|
g_signal_connect (priv->entry, "notify::justify",
|
|
|
|
G_CALLBACK (invalidate_shadow_pipeline), entry);
|
|
|
|
|
|
|
|
g_signal_connect (priv->entry, "notify::line-alignment",
|
|
|
|
G_CALLBACK (invalidate_shadow_pipeline), entry);
|
|
|
|
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
priv->spacing = 6.0f;
|
|
|
|
|
2018-11-24 11:37:19 +00:00
|
|
|
priv->text_shadow_material = NULL;
|
2017-06-05 17:39:21 +00:00
|
|
|
priv->shadow_width = -1.;
|
|
|
|
priv->shadow_height = -1.;
|
|
|
|
|
2012-02-13 20:22:53 +00:00
|
|
|
clutter_actor_add_child (CLUTTER_ACTOR (entry), priv->entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
clutter_actor_set_reactive ((ClutterActor *) entry, TRUE);
|
|
|
|
|
|
|
|
/* set cursor hidden until we receive focus */
|
|
|
|
clutter_text_set_cursor_visible ((ClutterText *) priv->entry, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_new:
|
2020-05-20 23:50:09 +00:00
|
|
|
* @text: (nullable): text to set the entry to
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Create a new #StEntry with the specified text.
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
|
|
|
* Returns: a new #StEntry
|
|
|
|
*/
|
|
|
|
StWidget *
|
|
|
|
st_entry_new (const gchar *text)
|
|
|
|
{
|
|
|
|
StWidget *entry;
|
|
|
|
|
|
|
|
/* add the entry to the stage, but don't allow it to be visible */
|
|
|
|
entry = g_object_new (ST_TYPE_ENTRY,
|
|
|
|
"text", text,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_get_text:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Get the text displayed on the entry. If @entry is empty, an empty string will
|
|
|
|
* be returned instead of %NULL.
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Returns: (transfer none): the text for the entry
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
2011-03-13 13:29:13 +00:00
|
|
|
const gchar *
|
2009-09-10 08:39:27 +00:00
|
|
|
st_entry_get_text (StEntry *entry)
|
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), NULL);
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2020-01-22 19:53:34 +00:00
|
|
|
|
|
|
|
return clutter_text_get_text (CLUTTER_TEXT (priv->entry));
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_set_text:
|
|
|
|
* @entry: a #StEntry
|
2014-05-28 19:54:02 +00:00
|
|
|
* @text: (nullable): text to set the entry to
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Sets the text displayed on the entry. If @text is %NULL, the #ClutterText
|
|
|
|
* will instead be set to an empty string.
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
st_entry_set_text (StEntry *entry,
|
|
|
|
const gchar *text)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
clutter_text_set_text (CLUTTER_TEXT (priv->entry), text);
|
|
|
|
|
2020-01-23 18:09:50 +00:00
|
|
|
/* Note: PROP_TEXT will get notfied from our notify::text handler connected
|
|
|
|
* to priv->entry. */
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_get_clutter_text:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Retrieve the internal #ClutterText so that extra parameters can be set.
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Returns: (transfer none): the #ClutterText used by @entry
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
ClutterActor*
|
|
|
|
st_entry_get_clutter_text (StEntry *entry)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (ST_ENTRY (entry), NULL);
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
return ((StEntryPrivate *)ST_ENTRY_PRIV (entry))->entry;
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_set_hint_text:
|
|
|
|
* @entry: a #StEntry
|
2014-05-28 19:54:02 +00:00
|
|
|
* @text: (nullable): text to set as the entry hint
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
|
|
|
* Sets the text to display when the entry is empty and unfocused. When the
|
2020-05-20 23:50:09 +00:00
|
|
|
* entry is displaying the hint, it has a pseudo class of `indeterminate`.
|
|
|
|
* A value of %NULL unsets the hint.
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
st_entry_set_hint_text (StEntry *entry,
|
|
|
|
const gchar *text)
|
|
|
|
{
|
2017-06-05 17:36:41 +00:00
|
|
|
StWidget *label;
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
label = st_label_new (text);
|
2020-01-20 14:27:26 +00:00
|
|
|
st_widget_add_style_class_name (label, "hint-text");
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
st_entry_set_hint_actor (ST_ENTRY (entry), CLUTTER_ACTOR (label));
|
2022-02-09 16:03:13 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_HINT_TEXT]);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_get_hint_text:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Gets the text that is displayed when the entry is empty and unfocused or
|
|
|
|
* %NULL if the #StEntry:hint-actor was set to an actor that is not a #StLabel.
|
2009-09-10 08:39:27 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Unlike st_entry_get_text() this function may return %NULL if
|
|
|
|
* #StEntry:hint-actor is not a #StLabel.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer none): the current value of the hint property
|
2009-09-10 08:39:27 +00:00
|
|
|
*/
|
2011-03-13 13:29:13 +00:00
|
|
|
const gchar *
|
2009-09-10 08:39:27 +00:00
|
|
|
st_entry_get_hint_text (StEntry *entry)
|
|
|
|
{
|
2017-06-05 17:36:41 +00:00
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), NULL);
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
priv = ST_ENTRY_PRIV (entry);
|
|
|
|
|
|
|
|
if (priv->hint_actor != NULL && ST_IS_LABEL (priv->hint_actor))
|
|
|
|
return st_label_get_text (ST_LABEL (priv->hint_actor));
|
|
|
|
|
|
|
|
return NULL;
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
2013-01-09 09:00:52 +00:00
|
|
|
/**
|
|
|
|
* st_entry_set_input_purpose:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
* @purpose: the purpose
|
|
|
|
*
|
|
|
|
* Sets the #StEntry:input-purpose property which
|
|
|
|
* can be used by on-screen keyboards and other input
|
|
|
|
* methods to adjust their behaviour.
|
|
|
|
*/
|
|
|
|
void
|
2017-12-14 16:19:01 +00:00
|
|
|
st_entry_set_input_purpose (StEntry *entry,
|
|
|
|
ClutterInputContentPurpose purpose)
|
2013-01-09 09:00:52 +00:00
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
2017-12-14 16:19:01 +00:00
|
|
|
ClutterText *editable;
|
2013-01-09 09:00:52 +00:00
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2017-12-14 16:19:01 +00:00
|
|
|
editable = CLUTTER_TEXT (priv->entry);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2017-12-14 16:19:01 +00:00
|
|
|
if (clutter_text_get_input_purpose (editable) != purpose)
|
2013-01-09 09:00:52 +00:00
|
|
|
{
|
2017-12-14 16:19:01 +00:00
|
|
|
clutter_text_set_input_purpose (editable, purpose);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2019-07-29 15:59:41 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_INPUT_PURPOSE]);
|
2013-01-09 09:00:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_get_input_purpose:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
|
|
|
* Gets the value of the #StEntry:input-purpose property.
|
2020-05-20 23:50:09 +00:00
|
|
|
*
|
|
|
|
* Returns: the input purpose of the entry
|
2013-01-09 09:00:52 +00:00
|
|
|
*/
|
2017-12-14 16:19:01 +00:00
|
|
|
ClutterInputContentPurpose
|
2013-01-09 09:00:52 +00:00
|
|
|
st_entry_get_input_purpose (StEntry *entry)
|
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
2017-12-14 16:19:01 +00:00
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2017-12-14 16:19:01 +00:00
|
|
|
return clutter_text_get_input_purpose (CLUTTER_TEXT (priv->entry));
|
2013-01-09 09:00:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_set_input_hints:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
* @hints: the hints
|
|
|
|
*
|
|
|
|
* Sets the #StEntry:input-hints property, which
|
|
|
|
* allows input methods to fine-tune their behaviour.
|
|
|
|
*/
|
|
|
|
void
|
2017-12-14 16:19:01 +00:00
|
|
|
st_entry_set_input_hints (StEntry *entry,
|
|
|
|
ClutterInputContentHintFlags hints)
|
2013-01-09 09:00:52 +00:00
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
2017-12-14 16:19:01 +00:00
|
|
|
ClutterText *editable;
|
2013-01-09 09:00:52 +00:00
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2017-12-14 16:19:01 +00:00
|
|
|
editable = CLUTTER_TEXT (priv->entry);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2017-12-14 16:19:01 +00:00
|
|
|
if (clutter_text_get_input_hints (editable) != hints)
|
2013-01-09 09:00:52 +00:00
|
|
|
{
|
2017-12-14 16:19:01 +00:00
|
|
|
clutter_text_set_input_hints (editable, hints);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2019-07-29 15:59:41 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_INPUT_HINTS]);
|
2013-01-09 09:00:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_get_input_hints:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
|
|
|
* Gets the value of the #StEntry:input-hints property.
|
2020-05-20 23:50:09 +00:00
|
|
|
*
|
|
|
|
* Returns: the input hints for the entry
|
2013-01-09 09:00:52 +00:00
|
|
|
*/
|
2017-12-14 16:19:01 +00:00
|
|
|
ClutterInputContentHintFlags
|
2013-01-09 09:00:52 +00:00
|
|
|
st_entry_get_input_hints (StEntry *entry)
|
|
|
|
{
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
2017-12-14 16:19:01 +00:00
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), 0);
|
2013-01-09 09:00:52 +00:00
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2017-12-14 16:19:01 +00:00
|
|
|
return clutter_text_get_input_hints (CLUTTER_TEXT (priv->entry));
|
2013-01-09 09:00:52 +00:00
|
|
|
}
|
|
|
|
|
2018-08-17 18:12:31 +00:00
|
|
|
static void
|
|
|
|
_st_entry_icon_clicked_cb (ClutterClickAction *action,
|
|
|
|
ClutterActor *actor,
|
|
|
|
StEntry *entry)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
2017-05-04 22:27:32 +00:00
|
|
|
StEntryPrivate *priv = ST_ENTRY_PRIV (entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
2020-09-09 18:51:53 +00:00
|
|
|
if (!clutter_actor_get_reactive (CLUTTER_ACTOR (entry)))
|
|
|
|
return;
|
|
|
|
|
2009-09-10 08:39:27 +00:00
|
|
|
if (actor == priv->primary_icon)
|
|
|
|
g_signal_emit (entry, entry_signals[PRIMARY_ICON_CLICKED], 0);
|
|
|
|
else
|
|
|
|
g_signal_emit (entry, entry_signals[SECONDARY_ICON_CLICKED], 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-02-10 18:40:01 +00:00
|
|
|
_st_entry_set_icon (StEntry *entry,
|
|
|
|
ClutterActor **icon,
|
|
|
|
ClutterActor *new_icon)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
|
|
|
if (*icon)
|
|
|
|
{
|
2018-08-17 18:12:31 +00:00
|
|
|
clutter_actor_remove_action_by_name (*icon, "entry-icon-action");
|
2012-02-13 20:22:53 +00:00
|
|
|
clutter_actor_remove_child (CLUTTER_ACTOR (entry), *icon);
|
2009-09-10 08:39:27 +00:00
|
|
|
*icon = NULL;
|
|
|
|
}
|
|
|
|
|
2011-02-10 18:40:01 +00:00
|
|
|
if (new_icon)
|
2009-09-10 08:39:27 +00:00
|
|
|
{
|
2018-08-17 18:12:31 +00:00
|
|
|
ClutterAction *action;
|
|
|
|
|
2011-02-10 18:40:01 +00:00
|
|
|
*icon = g_object_ref (new_icon);
|
2009-09-10 08:39:27 +00:00
|
|
|
|
|
|
|
clutter_actor_set_reactive (*icon, TRUE);
|
2012-02-13 20:22:53 +00:00
|
|
|
clutter_actor_add_child (CLUTTER_ACTOR (entry), *icon);
|
2018-08-17 18:12:31 +00:00
|
|
|
|
|
|
|
action = clutter_click_action_new ();
|
|
|
|
clutter_actor_add_action_with_name (*icon, "entry-icon-action", action);
|
|
|
|
g_signal_connect (action, "clicked",
|
|
|
|
G_CALLBACK (_st_entry_icon_clicked_cb), entry);
|
2009-09-10 08:39:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (entry));
|
|
|
|
}
|
|
|
|
|
2011-02-10 18:40:01 +00:00
|
|
|
/**
|
|
|
|
* st_entry_set_primary_icon:
|
|
|
|
* @entry: a #StEntry
|
2014-05-28 19:54:02 +00:00
|
|
|
* @icon: (nullable): a #ClutterActor
|
2011-02-10 18:40:01 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Set the primary icon of the entry to @icon.
|
2011-02-10 18:40:01 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
st_entry_set_primary_icon (StEntry *entry,
|
|
|
|
ClutterActor *icon)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2011-02-10 18:40:01 +00:00
|
|
|
|
2022-06-03 18:32:03 +00:00
|
|
|
if (priv->primary_icon == icon)
|
|
|
|
return;
|
|
|
|
|
2011-02-10 18:40:01 +00:00
|
|
|
_st_entry_set_icon (entry, &priv->primary_icon, icon);
|
2022-02-09 16:03:13 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_PRIMARY_ICON]);
|
2011-02-10 18:40:01 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 17:43:27 +00:00
|
|
|
/**
|
|
|
|
* st_entry_get_primary_icon:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Get the value of the #StEntry:primary-icon property.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer none): a #ClutterActor
|
2017-06-05 17:43:27 +00:00
|
|
|
*/
|
|
|
|
ClutterActor *
|
|
|
|
st_entry_get_primary_icon (StEntry *entry)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), NULL);
|
|
|
|
|
|
|
|
priv = ST_ENTRY_PRIV (entry);
|
|
|
|
return priv->primary_icon;
|
|
|
|
}
|
|
|
|
|
2011-02-10 18:40:01 +00:00
|
|
|
/**
|
|
|
|
* st_entry_set_secondary_icon:
|
|
|
|
* @entry: a #StEntry
|
2014-05-28 19:54:02 +00:00
|
|
|
* @icon: (nullable): an #ClutterActor
|
2011-02-10 18:40:01 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Set the secondary icon of the entry to @icon.
|
2011-02-10 18:40:01 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
st_entry_set_secondary_icon (StEntry *entry,
|
|
|
|
ClutterActor *icon)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
2011-02-10 18:40:01 +00:00
|
|
|
|
2022-06-03 18:32:03 +00:00
|
|
|
if (priv->secondary_icon == icon)
|
|
|
|
return;
|
|
|
|
|
2011-02-10 18:40:01 +00:00
|
|
|
_st_entry_set_icon (entry, &priv->secondary_icon, icon);
|
2022-02-09 16:03:13 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_SECONDARY_ICON]);
|
2011-02-10 18:40:01 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 17:43:27 +00:00
|
|
|
/**
|
|
|
|
* st_entry_get_secondary_icon:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Get the value of the #StEntry:secondary-icon property.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer none): a #ClutterActor
|
2017-06-05 17:43:27 +00:00
|
|
|
*/
|
|
|
|
ClutterActor *
|
|
|
|
st_entry_get_secondary_icon (StEntry *entry)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), NULL);
|
|
|
|
|
|
|
|
priv = ST_ENTRY_PRIV (entry);
|
|
|
|
return priv->secondary_icon;
|
|
|
|
}
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
/**
|
|
|
|
* st_entry_set_hint_actor:
|
|
|
|
* @entry: a #StEntry
|
2020-05-20 23:50:09 +00:00
|
|
|
* @hint_actor: (nullable): a #ClutterActor
|
2017-06-05 17:36:41 +00:00
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Set the hint actor of the entry to @hint_actor.
|
2017-06-05 17:36:41 +00:00
|
|
|
*/
|
|
|
|
void
|
|
|
|
st_entry_set_hint_actor (StEntry *entry,
|
|
|
|
ClutterActor *hint_actor)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_if_fail (ST_IS_ENTRY (entry));
|
|
|
|
|
|
|
|
priv = ST_ENTRY_PRIV (entry);
|
|
|
|
|
2022-06-03 18:32:03 +00:00
|
|
|
if (priv->hint_actor == hint_actor)
|
|
|
|
return;
|
|
|
|
|
2017-06-05 17:36:41 +00:00
|
|
|
if (priv->hint_actor != NULL)
|
|
|
|
{
|
|
|
|
clutter_actor_remove_child (CLUTTER_ACTOR (entry), priv->hint_actor);
|
|
|
|
priv->hint_actor = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hint_actor != NULL)
|
|
|
|
{
|
|
|
|
priv->hint_actor = hint_actor;
|
|
|
|
clutter_actor_add_child (CLUTTER_ACTOR (entry), priv->hint_actor);
|
|
|
|
}
|
|
|
|
|
|
|
|
st_entry_update_hint_visibility (entry);
|
2022-02-09 16:03:13 +00:00
|
|
|
g_object_notify_by_pspec (G_OBJECT (entry), props[PROP_HINT_ACTOR]);
|
2017-06-05 17:36:41 +00:00
|
|
|
|
|
|
|
clutter_actor_queue_relayout (CLUTTER_ACTOR (entry));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* st_entry_get_hint_actor:
|
|
|
|
* @entry: a #StEntry
|
|
|
|
*
|
2020-05-20 23:50:09 +00:00
|
|
|
* Get the value of the #StEntry:hint-actor property.
|
|
|
|
*
|
|
|
|
* Returns: (nullable) (transfer none): a #ClutterActor
|
2017-06-05 17:36:41 +00:00
|
|
|
*/
|
|
|
|
ClutterActor *
|
|
|
|
st_entry_get_hint_actor (StEntry *entry)
|
|
|
|
{
|
|
|
|
StEntryPrivate *priv;
|
|
|
|
|
|
|
|
g_return_val_if_fail (ST_IS_ENTRY (entry), NULL);
|
|
|
|
|
|
|
|
priv = ST_ENTRY_PRIV (entry);
|
|
|
|
return priv->hint_actor;
|
|
|
|
}
|
|
|
|
|
2012-02-07 17:29:58 +00:00
|
|
|
/******************************************************************************/
|
|
|
|
/*************************** ACCESSIBILITY SUPPORT ****************************/
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
#define ST_TYPE_ENTRY_ACCESSIBLE (st_entry_accessible_get_type ())
|
|
|
|
#define ST_ENTRY_ACCESSIBLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ST_TYPE_ENTRY_ACCESSIBLE, StEntryAccessible))
|
|
|
|
#define ST_IS_ENTRY_ACCESSIBLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ST_TYPE_ENTRY_ACCESSIBLE))
|
|
|
|
#define ST_ENTRY_ACCESSIBLE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), ST_TYPE_ENTRY_ACCESSIBLE, StEntryAccessibleClass))
|
|
|
|
#define ST_IS_ENTRY_ACCESSIBLE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), ST_TYPE_ENTRY_ACCESSIBLE))
|
|
|
|
#define ST_ENTRY_ACCESSIBLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ST_TYPE_ENTRY_ACCESSIBLE, StEntryAccessibleClass))
|
|
|
|
|
|
|
|
typedef struct _StEntryAccessible StEntryAccessible;
|
|
|
|
typedef struct _StEntryAccessibleClass StEntryAccessibleClass;
|
|
|
|
|
|
|
|
struct _StEntryAccessible
|
|
|
|
{
|
|
|
|
StWidgetAccessible parent;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _StEntryAccessibleClass
|
|
|
|
{
|
|
|
|
StWidgetAccessibleClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (StEntryAccessible, st_entry_accessible, ST_TYPE_WIDGET_ACCESSIBLE)
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_accessible_init (StEntryAccessible *self)
|
|
|
|
{
|
|
|
|
/* initialization done on AtkObject->initialize */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_accessible_initialize (AtkObject *obj,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
ATK_OBJECT_CLASS (st_entry_accessible_parent_class)->initialize (obj, data);
|
|
|
|
|
2017-12-14 16:19:01 +00:00
|
|
|
/* StEntry is behaving as a ClutterText container */
|
2012-02-07 17:29:58 +00:00
|
|
|
atk_object_set_role (obj, ATK_ROLE_PANEL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
st_entry_accessible_get_n_children (AtkObject *obj)
|
|
|
|
{
|
|
|
|
StEntry *entry = NULL;
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
2012-02-07 17:29:58 +00:00
|
|
|
|
|
|
|
g_return_val_if_fail (ST_IS_ENTRY_ACCESSIBLE (obj), 0);
|
|
|
|
|
|
|
|
entry = ST_ENTRY (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj)));
|
|
|
|
|
|
|
|
if (entry == NULL)
|
|
|
|
return 0;
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
|
|
|
if (priv->entry == NULL)
|
2012-02-07 17:29:58 +00:00
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static AtkObject*
|
|
|
|
st_entry_accessible_ref_child (AtkObject *obj,
|
|
|
|
gint i)
|
|
|
|
{
|
|
|
|
StEntry *entry = NULL;
|
2015-09-24 14:08:13 +00:00
|
|
|
StEntryPrivate *priv;
|
2012-02-07 17:29:58 +00:00
|
|
|
AtkObject *result = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (ST_IS_ENTRY_ACCESSIBLE (obj), NULL);
|
|
|
|
g_return_val_if_fail (i == 0, NULL);
|
|
|
|
|
|
|
|
entry = ST_ENTRY (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj)));
|
|
|
|
|
|
|
|
if (entry == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
priv = st_entry_get_instance_private (entry);
|
|
|
|
if (priv->entry == NULL)
|
2012-02-07 17:29:58 +00:00
|
|
|
return NULL;
|
|
|
|
|
2015-09-24 14:08:13 +00:00
|
|
|
result = clutter_actor_get_accessible (priv->entry);
|
2012-02-07 17:29:58 +00:00
|
|
|
g_object_ref (result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
st_entry_accessible_class_init (StEntryAccessibleClass *klass)
|
|
|
|
{
|
|
|
|
AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
atk_class->initialize = st_entry_accessible_initialize;
|
|
|
|
atk_class->get_n_children = st_entry_accessible_get_n_children;
|
|
|
|
atk_class->ref_child= st_entry_accessible_ref_child;
|
|
|
|
}
|