Merge branch 'wip/otte/inscription' into 'main'

Add GtkInscription

See merge request GNOME/gtk!4800
This commit is contained in:
Matthias Clasen 2022-06-11 13:47:20 +00:00
commit c7c8b37e4c
17 changed files with 1805 additions and 64 deletions

View File

@ -17,10 +17,9 @@ const char *factory_text =
"<interface>\n"
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkLabel'>\n"
" <property name='ellipsize'>end</property>\n"
" <object class='GtkInscription'>\n"
" <property name='xalign'>0</property>\n"
" <binding name='label'>\n"
" <binding name='text'>\n"
" <lookup name='string' type='GtkStringObject'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"
" </lookup>\n"

View File

@ -7,9 +7,9 @@
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<object class="GtkInscription">
<property name="hexpand">1</property>
<binding name="text">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
</lookup>

View File

@ -32,6 +32,7 @@
#include "gtkatcontextprivate.h"
#include "gtkdebug.h"
#include "gtkeditable.h"
#include "gtkinscriptionprivate.h"
#include "gtklabelprivate.h"
#include "gtkentryprivate.h"
#include "gtksearchentryprivate.h"
@ -406,6 +407,274 @@ static const GDBusInterfaceVTable label_vtable = {
NULL,
};
/* }}} */
/* {{{ GtkInscription */
static void
inscription_handle_method (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
GtkATContext *self = user_data;
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
GtkWidget *widget = GTK_WIDGET (accessible);
if (g_strcmp0 (method_name, "GetCaretOffset") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", 0));
}
else if (g_strcmp0 (method_name, "SetCaretOffset") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "GetText") == 0)
{
int start, end;
const char *text;
int len;
char *string;
g_variant_get (parameters, "(ii)", &start, &end);
text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
len = g_utf8_strlen (text, -1);
start = CLAMP (start, 0, len);
end = CLAMP (end, 0, len);
if (end <= start)
string = g_strdup ("");
else
{
const char *p, *q;
p = g_utf8_offset_to_pointer (text, start);
q = g_utf8_offset_to_pointer (text, end);
string = g_strndup (p, q - p);
}
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", string));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetTextBeforeOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextBoundaryType boundary_type;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &boundary_type);
string = gtk_pango_get_text_before (layout, offset, boundary_type, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetTextAtOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextBoundaryType boundary_type;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &boundary_type);
string = gtk_pango_get_text_at (layout, offset, boundary_type, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetTextAfterOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextBoundaryType boundary_type;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &boundary_type);
string = gtk_pango_get_text_after (layout, offset, boundary_type, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetCharacterAtOffset") == 0)
{
int offset;
const char *text;
gunichar ch = 0;
g_variant_get (parameters, "(i)", &offset);
text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
if (0 <= offset && offset < g_utf8_strlen (text, -1))
ch = g_utf8_get_char (g_utf8_offset_to_pointer (text, offset));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", ch));
}
else if (g_strcmp0 (method_name, "GetStringAtOffset") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
int offset;
AtspiTextGranularity granularity;
char *string;
int start, end;
g_variant_get (parameters, "(iu)", &offset, &granularity);
string = gtk_pango_get_string_at (layout, offset, granularity, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(sii)", string, start, end));
g_free (string);
}
else if (g_strcmp0 (method_name, "GetAttributes") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
int start, end;
g_variant_get (parameters, "(i)", &offset);
gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
}
else if (g_strcmp0 (method_name, "GetAttributeValue") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
const char *name;
int start, end;
GVariant *attrs;
const char *val;
g_variant_get (parameters, "(i&s)", &offset, &name);
gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
attrs = g_variant_builder_end (&builder);
if (!g_variant_lookup (attrs, name, "&s", &val))
val = "";
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", val));
g_variant_unref (attrs);
}
else if (g_strcmp0 (method_name, "GetAttributeRun") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
int offset;
gboolean include_defaults;
int start, end;
g_variant_get (parameters, "(ib)", &offset, &include_defaults);
if (include_defaults)
gtk_pango_get_default_attributes (layout, &builder);
gtk_pango_get_run_attributes (layout, &builder, offset, &start, &end);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss}ii)", &builder, start, end));
}
else if (g_strcmp0 (method_name, "GetDefaultAttributes") == 0 ||
g_strcmp0 (method_name, "GetDefaultAttributeSet") == 0)
{
PangoLayout *layout = gtk_inscription_get_layout (GTK_INSCRIPTION (widget));;
GVariantBuilder builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE ("a{ss}"));
gtk_pango_get_default_attributes (layout, &builder);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(a{ss})", &builder));
}
else if (g_strcmp0 (method_name, "GetNSelections") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(i)", 0));
}
else if (g_strcmp0 (method_name, "GetSelection") == 0)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "No selections available");
}
else if (g_strcmp0 (method_name, "AddSelection") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "RemoveSelection") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "SetSelection") == 0)
{
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
}
else if (g_strcmp0 (method_name, "GetCharacterExtents") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "GetRangeExtents") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "GetBoundedRanges") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "ScrollSubstringTo") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
else if (g_strcmp0 (method_name, "ScrollSubstringToPoint") == 0)
{
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
}
}
static GVariant *
inscription_get_property (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *property_name,
GError **error,
gpointer user_data)
{
GtkATContext *self = user_data;
GtkAccessible *accessible = gtk_at_context_get_accessible (self);
GtkWidget *widget = GTK_WIDGET (accessible);
if (g_strcmp0 (property_name, "CharacterCount") == 0)
{
const char *text;
int len;
text = gtk_inscription_get_text (GTK_INSCRIPTION (widget));
len = g_utf8_strlen (text, -1);
return g_variant_new_int32 (len);
}
else if (g_strcmp0 (property_name, "CaretOffset") == 0)
{
return g_variant_new_int32 (0);
}
return NULL;
}
static const GDBusInterfaceVTable inscription_vtable = {
inscription_handle_method,
inscription_get_property,
NULL,
};
/* }}} */
/* {{{ GtkEditable */
@ -1301,6 +1570,8 @@ gtk_atspi_get_text_vtable (GtkAccessible *accessible)
{
if (GTK_IS_LABEL (accessible))
return &label_vtable;
else if (GTK_IS_INSCRIPTION (accessible))
return &inscription_vtable;
else if (GTK_IS_EDITABLE (accessible) &&
GTK_IS_TEXT (gtk_editable_get_delegate (GTK_EDITABLE (accessible))))
return &editable_vtable;

View File

@ -155,6 +155,7 @@
#include <gtk/gtkimcontextsimple.h>
#include <gtk/gtkimmulticontext.h>
#include <gtk/gtkinfobar.h>
#include <gtk/gtkinscription.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklayoutmanager.h>
#include <gtk/gtklayoutchild.h>

1191
gtk/gtkinscription.c Normal file

File diff suppressed because it is too large Load Diff

109
gtk/gtkinscription.h Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright © 2022 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_INSCRIPTION_H__
#define __GTK_INSCRIPTION_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
#define GTK_TYPE_INSCRIPTION (gtk_inscription_get_type ())
/**
* GtkInscriptionOverflow:
* @GTK_INSCRIPTION_OVERFLOW_CLIP: Clip the remaining text
* @GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_START: Omit characters at the start of the text
* @GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_MIDDLE: Omit characters at the middle of the text
* @GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_END: Omit characters at the end of the text
*
* The different methods to handle text in #GtkInscription when it doesn't
* fit the available space.
*/
typedef enum {
GTK_INSCRIPTION_OVERFLOW_CLIP,
GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_START,
GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_MIDDLE,
GTK_INSCRIPTION_OVERFLOW_ELLIPSIZE_END
} GtkInscriptionOverflow;
GDK_AVAILABLE_IN_4_8
G_DECLARE_FINAL_TYPE (GtkInscription, gtk_inscription, GTK, INSCRIPTION, GtkWidget)
GDK_AVAILABLE_IN_4_8
GtkWidget * gtk_inscription_new (const char *text);
GDK_AVAILABLE_IN_4_8
const char * gtk_inscription_get_text (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_text (GtkInscription *self,
const char *text);
GDK_AVAILABLE_IN_4_8
PangoAttrList * gtk_inscription_get_attributes (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_attributes (GtkInscription *self,
PangoAttrList *attrs);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_markup (GtkInscription *self,
const char *markup);
GDK_AVAILABLE_IN_4_8
GtkInscriptionOverflow gtk_inscription_get_text_overflow (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_text_overflow (GtkInscription *self,
GtkInscriptionOverflow overflow);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_min_chars (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_min_chars (GtkInscription *self,
guint min_chars);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_nat_chars (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_nat_chars (GtkInscription *self,
guint nat_chars);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_min_lines (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_min_lines (GtkInscription *self,
guint min_lines);
GDK_AVAILABLE_IN_4_8
guint gtk_inscription_get_nat_lines (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_nat_lines (GtkInscription *self,
guint nat_lines);
GDK_AVAILABLE_IN_4_8
float gtk_inscription_get_xalign (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_xalign (GtkInscription *self,
float xalign);
GDK_AVAILABLE_IN_4_8
float gtk_inscription_get_yalign (GtkInscription *self);
GDK_AVAILABLE_IN_4_8
void gtk_inscription_set_yalign (GtkInscription *self,
float yalign);
G_END_DECLS
#endif /* __GTK_INSCRIPTION_H__ */

View File

@ -0,0 +1,33 @@
/*
* Copyright © 2022 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_INSCRIPTION_PRIVATE_H__
#define __GTK_INSCRIPTION_PRIVATE_H__
#include <gtk/gtkinscription.h>
G_BEGIN_DECLS
PangoLayout * gtk_inscription_get_layout (GtkInscription *self);
G_END_DECLS
#endif /* __GTK_INSCRIPTION_PRIVATE_H__ */

View File

@ -31,7 +31,7 @@
G_BEGIN_DECLS
PangoAttrList *_gtk_pango_attr_list_merge (PangoAttrList *into,
PangoAttrList *from);
PangoAttrList *from) G_GNUC_WARN_UNUSED_RESULT;
gboolean gtk_buildable_attribute_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,

View File

@ -41,6 +41,7 @@
#include "gtkflattenlistmodel.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkiconview.h"
#include "gtkinscription.h"
#include "gtklabel.h"
#include "gtklistitem.h"
#include "gtkpopover.h"
@ -835,6 +836,8 @@ match_object (GObject *object,
if (GTK_IS_LABEL (object))
return match_string (gtk_label_get_label (GTK_LABEL (object)), text);
if (GTK_IS_INSCRIPTION (object))
return match_string (gtk_inscription_get_text (GTK_INSCRIPTION (object)), text);
else if (GTK_IS_BUTTON (object))
return match_string (gtk_button_get_label (GTK_BUTTON (object)), text);
else if (GTK_IS_WINDOW (object))
@ -975,24 +978,23 @@ static void
setup_type_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *expander, *label;
GtkWidget *expander, *inscription;
/* expander */
expander = gtk_tree_expander_new ();
gtk_list_item_set_child (list_item, expander);
/* label */
label = gtk_label_new (NULL);
gtk_label_set_width_chars (GTK_LABEL (label), 30);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), label);
inscription = gtk_inscription_new (NULL);
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (inscription), 30);
gtk_tree_expander_set_child (GTK_TREE_EXPANDER (expander), inscription);
}
static void
bind_type_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *expander, *label;
GtkWidget *expander, *inscription;
GtkTreeListRow *list_row;
gpointer item;
@ -1001,17 +1003,17 @@ bind_type_cb (GtkSignalListItemFactory *factory,
gtk_tree_expander_set_list_row (GTK_TREE_EXPANDER (expander), list_row);
item = gtk_tree_list_row_get_item (list_row);
expander = gtk_list_item_get_child (list_item);
label = gtk_tree_expander_get_child (GTK_TREE_EXPANDER (expander));
inscription = gtk_tree_expander_get_child (GTK_TREE_EXPANDER (expander));
gtk_label_set_label (GTK_LABEL (label), G_OBJECT_TYPE_NAME (item));
gtk_inscription_set_text (GTK_INSCRIPTION (inscription), G_OBJECT_TYPE_NAME (item));
if (GTK_IS_WIDGET (item))
{
g_signal_connect (item, "map", G_CALLBACK (widget_mapped), label);
g_signal_connect (item, "unmap", G_CALLBACK (widget_unmapped), label);
g_signal_connect (item, "map", G_CALLBACK (widget_mapped), inscription);
g_signal_connect (item, "unmap", G_CALLBACK (widget_unmapped), inscription);
if (!gtk_widget_get_mapped (item))
widget_unmapped (item, label);
g_object_set_data (G_OBJECT (label), "binding", g_object_ref (item));
widget_unmapped (item, inscription);
g_object_set_data (G_OBJECT (inscription), "binding", g_object_ref (item));
}
g_object_unref (item);
@ -1040,26 +1042,24 @@ static void
setup_name_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *label;
GtkWidget *inscription;
label = gtk_label_new (NULL);
gtk_label_set_width_chars (GTK_LABEL (label), 15);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_list_item_set_child (list_item, label);
inscription = gtk_inscription_new (NULL);
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (inscription), 15);
gtk_list_item_set_child (list_item, inscription);
}
static void
bind_name_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *label;
GtkWidget *inscription;
gpointer item;
item = gtk_tree_list_row_get_item (gtk_list_item_get_item (list_item));
label = gtk_list_item_get_child (list_item);
inscription = gtk_list_item_get_child (list_item);
gtk_label_set_label (GTK_LABEL (label), gtk_inspector_get_object_name (item));
gtk_inscription_set_text (GTK_INSCRIPTION (inscription), gtk_inspector_get_object_name (item));
g_object_unref (item);
}
@ -1068,54 +1068,54 @@ static void
setup_label_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *label;
GtkWidget *inscription;
label = gtk_label_new (NULL);
gtk_label_set_width_chars (GTK_LABEL (label), 25);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_list_item_set_child (list_item, label);
inscription = gtk_inscription_new (NULL);
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (inscription), 25);
gtk_list_item_set_child (list_item, inscription);
}
static void
bind_label_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *label;
GtkWidget *inscription;
gpointer item;
GBinding *binding = NULL;
item = gtk_tree_list_row_get_item (gtk_list_item_get_item (list_item));
label = gtk_list_item_get_child (list_item);
inscription = gtk_list_item_get_child (list_item);
if (GTK_IS_LABEL (item))
binding = g_object_bind_property (item, "label", label, "label", G_BINDING_SYNC_CREATE);
binding = g_object_bind_property (item, "label", inscription, "text", G_BINDING_SYNC_CREATE);
if (GTK_IS_INSCRIPTION (item))
binding = g_object_bind_property (item, "text", inscription, "text", G_BINDING_SYNC_CREATE);
else if (GTK_IS_BUTTON (item))
binding = g_object_bind_property (item, "label", label, "label", G_BINDING_SYNC_CREATE);
binding = g_object_bind_property (item, "label", inscription, "text", G_BINDING_SYNC_CREATE);
else if (GTK_IS_WINDOW (item))
binding = g_object_bind_property (item, "title", label, "label", G_BINDING_SYNC_CREATE);
binding = g_object_bind_property (item, "title", inscription, "text", G_BINDING_SYNC_CREATE);
else if (GTK_IS_TREE_VIEW_COLUMN (item))
binding = g_object_bind_property (item, "title", label, "label", G_BINDING_SYNC_CREATE);
binding = g_object_bind_property (item, "title", inscription, "text", G_BINDING_SYNC_CREATE);
else if (GTK_IS_EDITABLE (item))
binding = g_object_bind_property (item, "text", label, "label", G_BINDING_SYNC_CREATE);
binding = g_object_bind_property (item, "text", inscription, "text", G_BINDING_SYNC_CREATE);
else
gtk_label_set_label (GTK_LABEL (label), NULL);
gtk_inscription_set_text (GTK_INSCRIPTION (inscription), NULL);
g_object_unref (item);
if (binding)
g_object_set_data (G_OBJECT (label), "binding", binding);
g_object_set_data (G_OBJECT (inscription), "binding", binding);
}
static void
unbind_label_cb (GtkSignalListItemFactory *factory,
GtkListItem *list_item)
{
GtkWidget *label;
GtkWidget *inscription;
GBinding *binding;
label = gtk_list_item_get_child (list_item);
binding = g_object_steal_data (G_OBJECT (label), "binding");
inscription = gtk_list_item_get_child (list_item);
binding = g_object_steal_data (G_OBJECT (inscription), "binding");
if (binding)
g_binding_unbind (binding);
}

View File

@ -24,7 +24,7 @@
#include <gtk/gtkdragsource.h>
#include <gtk/gtkeventcontroller.h>
#include <gtk/gtkfilechooserdialog.h>
#include <gtk/gtksignallistitemfactory.h>
#include <gtk/gtkinscription.h>
#include <gtk/gtklabel.h>
#include <gtk/gtklistbox.h>
#include <gtk/gtklistitem.h>
@ -33,6 +33,7 @@
#include <gtk/gtkmessagedialog.h>
#include <gtk/gtkpicture.h>
#include <gtk/gtkpopover.h>
#include <gtk/gtksignallistitemfactory.h>
#include <gtk/gtksingleselection.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtktreeexpander.h>
@ -401,7 +402,8 @@ setup_widget_for_render_node (GtkSignalListItemFactory *factory,
gtk_box_append (GTK_BOX (box), child);
/* name */
child = gtk_label_new (NULL);
child = gtk_inscription_new (NULL);
gtk_widget_set_hexpand (child, TRUE);
gtk_box_append (GTK_BOX (box), child);
}
@ -431,7 +433,7 @@ bind_widget_for_render_node (GtkSignalListItemFactory *factory,
/* name */
name = node_name (node);
child = gtk_widget_get_last_child (box);
gtk_label_set_label (GTK_LABEL (child), name);
gtk_inscription_set_text (GTK_INSCRIPTION (child), name);
g_free (name);
g_object_unref (paintable);

View File

@ -283,6 +283,7 @@ gtk_public_sources = files([
'gtkimmodule.c',
'gtkimmulticontext.c',
'gtkinfobar.c',
'gtkinscription.c',
'gtklabel.c',
'gtklayoutchild.c',
'gtklayoutmanager.c',
@ -570,6 +571,7 @@ gtk_public_headers = files([
'gtkimmodule.h',
'gtkimmulticontext.h',
'gtkinfobar.h',
'gtkinscription.h',
'gtklabel.h',
'gtklayoutchild.h',
'gtklayoutmanager.h',

View File

@ -200,7 +200,7 @@ row_data_bind (RowData *data,
row_data_update_info (data, info);
gtk_label_set_label (GTK_LABEL (data->name), g_file_info_get_display_name (info));
gtk_inscription_set_text (GTK_LABEL (data->name), g_file_info_get_display_name (info));
g_object_unref (info);
}
@ -237,10 +237,10 @@ setup_widget (GtkListItem *list_item,
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
gtk_container_add (GTK_CONTAINER (list_item), box);
child = gtk_label_new (NULL);
gtk_label_set_width_chars (GTK_LABEL (child), 5);
gtk_label_set_xalign (GTK_LABEL (child), 1.0);
g_object_bind_property (list_item, "position", child, "label", G_BINDING_SYNC_CREATE);
child = gtk_inscription_new (NULL);
gtk_inscription_set_min_chars (GTK_LABEL (child), 5);
gtk_inscription_set_xalign (GTK_LABEL (child), 1.0);
g_object_bind_property (list_item, "position", child, "text", G_BINDING_SYNC_CREATE);
gtk_container_add (GTK_CONTAINER (box), child);
data->expander = gtk_tree_expander_new ();
@ -252,9 +252,8 @@ setup_widget (GtkListItem *list_item,
data->icon = gtk_image_new ();
gtk_container_add (GTK_CONTAINER (box), data->icon);
data->name = gtk_label_new (NULL);
gtk_label_set_max_width_chars (GTK_LABEL (data->name), 25);
gtk_label_set_ellipsize (GTK_LABEL (data->name), PANGO_ELLIPSIZE_END);
data->name = gtk_inscription_new (NULL);
gtk_inscription_set_nat_chars (GTK_LABEL (data->name), 25);
gtk_container_add (GTK_CONTAINER (box), data->name);
}
#endif
@ -441,10 +440,8 @@ const char *ui_file =
" </object>\n"
" </child>\n"
" <child>\n"
" <object class='GtkLabel'>\n"
" <property name='halign'>start</property>\n"
" <property name='label'>start</property>\n"
" <binding name='label'>\n"
" <object class='GtkInscription'>\n"
" <binding name='text'>\n"
" <closure type='gchararray' function='get_string'>\n"
" <lookup name='item'>expander</lookup>\n"
" <constant type='gchararray'>standard::display-name</constant>"
@ -480,9 +477,8 @@ const char *ui_file =
"<interface>\n" \
" <template class='GtkListItem'>\n" \
" <property name='child'>\n" \
" <object class='GtkLabel'>\n" \
" <property name='halign'>start</property>\n" \
" <binding name='label'>\n" \
" <object class='GtkInscription'>\n" \
" <binding name='text'>\n" \
" <closure type='gchararray' function='get_string'>\n" \
" <lookup name='item' type='GtkTreeListRow'><lookup name='item'>GtkListItem</lookup></lookup>\n" \
" <constant type='gchararray'>" attr "</constant>" \
@ -623,6 +619,7 @@ const char *factory_ui =
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkLabel'>\n"
" <property name='xalign'>0</property>\n"
" <binding name='label'>\n"
" <lookup name='title' type='GtkColumnViewColumn'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="default-width">800</property>
<property name="default-height">600</property>
<child>
<object class="GtkLabel">
<property name="use-markup">1</property>
<property name="wrap">1</property>
<property name="label" translatable="yes">Text sizes: &lt;span size="xx-small"&gt;tiny &lt;/span&gt;&lt;span size="x-small"&gt;very small &lt;/span&gt;&lt;span size="small"&gt;small &lt;/span&gt;&lt;span size="medium"&gt;normal &lt;/span&gt;&lt;span size="large"&gt;large &lt;/span&gt;&lt;span size="x-large"&gt;very large &lt;/span&gt;&lt;span size="xx-large"&gt;huge&lt;/span&gt;
Text styles: &lt;span style="normal"&gt;Normal&lt;/span&gt; &lt;span style="italic"&gt;Italic&lt;/span&gt; &lt;span style="oblique"&gt;Olique&lt;/span&gt;
Text weights: &lt;span weight="thin"&gt;thin&lt;/span&gt; &lt;span weight="light"&gt;light&lt;/span&gt; &lt;span weight="normal"&gt;normal&lt;/span&gt; &lt;span weight="bold"&gt;bold&lt;/span&gt; &lt;span weight="ultraheavy"&gt;ultraheavy&lt;/span&gt;
Text &lt;span color="gray"&gt;c&lt;span color="green"&gt;o&lt;/span&gt;l&lt;span color="tomato"&gt;o&lt;/span&gt;rs&lt;/span&gt; and &lt;span background="pink"&gt;backgrounds&lt;/span&gt;
Colorful &lt;span underline="low" underline-color="blue"&gt;&lt;span underline="double" underline-color="red"&gt;under&lt;/span&gt;lines&lt;/span&gt; and &lt;span background="pink"&gt;&lt;span underline="error"&gt;mo&lt;/span&gt;&lt;span underline="error" underline-color="green"&gt;re&lt;/span&gt;&lt;/span&gt;
Colorful &lt;span strikethrough="true" strikethrough-color="magenta"&gt;strikethroughs&lt;/span&gt; and &lt;span overline="single" overline_color="green"&gt;overlines&lt;/span&gt;
Superscripts and subscripts: 𝜀&lt;span rise="-6000" size="x-small" font_desc="italic"&gt;0&lt;/span&gt; = 𝜔&lt;span rise="8000" size="smaller"&gt;𝜔&lt;span rise="14000" size="smaller"&gt;𝜔&lt;span rise="20000"&gt;.&lt;span rise="23000"&gt;.&lt;span rise="26000"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span letter_spacing="3000"&gt;Letterspacing&lt;/span&gt;
OpenType font features: &lt;span font_desc="sans regular" font_features="dlig=0"&gt;feast&lt;/span&gt; versus &lt;span font_desc="sans regular" font_features="dlig=1"&gt;feast&lt;/span&gt;
Shortcuts: &lt;tt&gt;Monospace&lt;/tt&gt; &lt;b&gt;Bold&lt;/b&gt; &lt;i&gt;Italic&lt;/i&gt; &lt;big&gt;Big&lt;/big&gt; &lt;small&gt;Small&lt;/small&gt; &lt;u&gt;Underlined&lt;/u&gt; &lt;s&gt;Strikethrough&lt;/s&gt; Super&lt;sup&gt;script&lt;/sup&gt; Sub&lt;sub&gt;script&lt;/sub&gt;
hy­phen­ation al­go­rithm is a &lt;span allow_breaks="false" style="italic"&gt;set of rules&lt;/span&gt;, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
&lt;span insert_hyphens="false"&gt;one/two three/four five/six seven/eight nine/ten&lt;/span&gt;
&lt;span line_height='1.33'&gt;Line height: This is an example of widely spaced text. It was achieved by setting the line-height factor to 1.33. You can set the line-height factor to any value between 0 and 10.
Note that the line height affects the spacing between paragraphs as well as between the wrapped lines inside a paragraph.&lt;/span&gt;
Transforms: &lt;span text_transform='uppercase'&gt;straße&lt;/span&gt; &lt;span text_transform='capitalize'&gt;up, up and away&lt;/span&gt;</property>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="decorated">0</property>
<property name="default-width">800</property>
<property name="default-height">600</property>
<child>
<object class="GtkInscription">
<property name="markup" translatable="yes">Text sizes: &lt;span size="xx-small"&gt;tiny &lt;/span&gt;&lt;span size="x-small"&gt;very small &lt;/span&gt;&lt;span size="small"&gt;small &lt;/span&gt;&lt;span size="medium"&gt;normal &lt;/span&gt;&lt;span size="large"&gt;large &lt;/span&gt;&lt;span size="x-large"&gt;very large &lt;/span&gt;&lt;span size="xx-large"&gt;huge&lt;/span&gt;
Text styles: &lt;span style="normal"&gt;Normal&lt;/span&gt; &lt;span style="italic"&gt;Italic&lt;/span&gt; &lt;span style="oblique"&gt;Olique&lt;/span&gt;
Text weights: &lt;span weight="thin"&gt;thin&lt;/span&gt; &lt;span weight="light"&gt;light&lt;/span&gt; &lt;span weight="normal"&gt;normal&lt;/span&gt; &lt;span weight="bold"&gt;bold&lt;/span&gt; &lt;span weight="ultraheavy"&gt;ultraheavy&lt;/span&gt;
Text &lt;span color="gray"&gt;c&lt;span color="green"&gt;o&lt;/span&gt;l&lt;span color="tomato"&gt;o&lt;/span&gt;rs&lt;/span&gt; and &lt;span background="pink"&gt;backgrounds&lt;/span&gt;
Colorful &lt;span underline="low" underline-color="blue"&gt;&lt;span underline="double" underline-color="red"&gt;under&lt;/span&gt;lines&lt;/span&gt; and &lt;span background="pink"&gt;&lt;span underline="error"&gt;mo&lt;/span&gt;&lt;span underline="error" underline-color="green"&gt;re&lt;/span&gt;&lt;/span&gt;
Colorful &lt;span strikethrough="true" strikethrough-color="magenta"&gt;strikethroughs&lt;/span&gt; and &lt;span overline="single" overline_color="green"&gt;overlines&lt;/span&gt;
Superscripts and subscripts: 𝜀&lt;span rise="-6000" size="x-small" font_desc="italic"&gt;0&lt;/span&gt; = 𝜔&lt;span rise="8000" size="smaller"&gt;𝜔&lt;span rise="14000" size="smaller"&gt;𝜔&lt;span rise="20000"&gt;.&lt;span rise="23000"&gt;.&lt;span rise="26000"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span letter_spacing="3000"&gt;Letterspacing&lt;/span&gt;
OpenType font features: &lt;span font_desc="sans regular" font_features="dlig=0"&gt;feast&lt;/span&gt; versus &lt;span font_desc="sans regular" font_features="dlig=1"&gt;feast&lt;/span&gt;
Shortcuts: &lt;tt&gt;Monospace&lt;/tt&gt; &lt;b&gt;Bold&lt;/b&gt; &lt;i&gt;Italic&lt;/i&gt; &lt;big&gt;Big&lt;/big&gt; &lt;small&gt;Small&lt;/small&gt; &lt;u&gt;Underlined&lt;/u&gt; &lt;s&gt;Strikethrough&lt;/s&gt; Super&lt;sup&gt;script&lt;/sup&gt; Sub&lt;sub&gt;script&lt;/sub&gt;
hy­phen­ation al­go­rithm is a &lt;span allow_breaks="false" style="italic"&gt;set of rules&lt;/span&gt;, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
&lt;span insert_hyphens="false"&gt;one/two three/four five/six seven/eight nine/ten&lt;/span&gt;
&lt;span line_height='1.33'&gt;Line height: This is an example of widely spaced text. It was achieved by setting the line-height factor to 1.33. You can set the line-height factor to any value between 0 and 10.
Note that the line height affects the spacing between paragraphs as well as between the wrapped lines inside a paragraph.&lt;/span&gt;
Transforms: &lt;span text_transform='uppercase'&gt;straße&lt;/span&gt; &lt;span text_transform='capitalize'&gt;up, up and away&lt;/span&gt;</property>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="default-width">200</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkOverlay">
<child>
<object class="GtkLabel" />
</child>
<child type="overlay">
<object class="GtkLabel">
<property name="label" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="ellipsize">start</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="ellipsize">middle</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow">
<property name="default-width">200</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkInscription">
<property name="text" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="text-overflow">clip</property>
</object>
</child>
<child>
<object class="GtkInscription">
<property name="text" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="text-overflow">ellipsize-start</property>
</object>
</child>
<child>
<object class="GtkInscription">
<property name="text" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="text-overflow">ellipsize-middle</property>
</object>
</child>
<child>
<object class="GtkInscription">
<property name="text" translatable="yes">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</property>
<property name="text-overflow">ellipsize-end</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@ -367,6 +367,10 @@ testdata = [
'image-load-from-file.css',
'image-load-from-file.ref.ui',
'image-load-from-file.ui',
'inscription-markup.ref.ui',
'inscription-markup.ui',
'inscription-overflow.ref.ui',
'inscription-overflow.ui',
'label-attribute-preference.css',
'label-attribute-preference.ref.ui',
'label-attribute-preference.ui',