Compare commits

..

12 Commits

Author SHA1 Message Date
Matthias Clasen dc6c27fb88 GtkCenterBox: Implement baseline support 2017-06-04 15:57:58 -04:00
Matthias Clasen ebabb4bf30 GtkCenterBox: implement GtkOrientable
This is generally expected of containers.
2017-06-04 13:28:43 -04:00
Matthias Clasen 1c17f382a5 Keep GtkCenterBox struct private
No need to derive from this.
2017-06-04 12:45:21 -04:00
Matthias Clasen 35d8c85667 centerbox: do height-for-width properly 2017-06-04 10:11:42 -04:00
Matthias Clasen 9b1f4b4a90 Make expand work for the center box children
We expand the center child first, but only to as far
as we can keep it centered.
2017-06-03 23:19:57 -04:00
Matthias Clasen 149c2cc3d8 Improve the center box test 2017-06-03 16:09:39 -04:00
Matthias Clasen b095bf05c2 Make GtkCenterBox buildable 2017-06-03 16:04:57 -04:00
Matthias Clasen cd43686289 center box: implement natural size and rtl flipping
We prefer to give the center widget its natural size,
and we center it as long as possible.
2017-06-03 15:56:01 -04:00
Matthias Clasen 3dc7e71c32 center box: handle missing start or end widgets 2017-06-03 13:17:19 -04:00
Matthias Clasen 433082f050 Add a trivial center box test 2017-06-03 09:16:02 -04:00
Matthias Clasen 81049ea5c5 export the center box api
Without this, its not a public api after all...
2017-06-03 09:08:13 -04:00
Matthias Clasen 4c90d61c05 Make GtkCenterBox public
This is functionality we used to have, and it is generally useful.
2017-06-02 22:25:55 -04:00
365 changed files with 46385 additions and 35947 deletions
-108
View File
@@ -1,111 +1,3 @@
Overview of Changes in GTK+ 3.91.2
==================================
* All widgets are drawing CSS backgrounds and borders
* All gadgets have been replaced by widgets
* GtkSpinButton no longer derives from GtkEntry
* GtkScrollbar no longer derives from GtkRange
* GtkAccelLabel no longer derives from GtkLabel
* All remaining style properties have been removed
* A new 'widget bowl' demo has been added in gtk4-demo
* GtkEventBox has been removed. It is no longer needed
* Add support for entering emoji by name using Ctrl-Shift-e
* Wayland:
- Support Wacom tablet wheel scrolling
- Support the shortcut inhibitor protocol
* Bugs fixed:
776903 Label with hyperlinks cannot be opened with touch on wayland
776909 gtk_adjustment_clamp_page: Conditional jump or move depends on unin...
777333 In a GNOME Wayland session, gnome-terminal windows cannot be moved ...
777515 gtk3-icon-browser doesn't list document-edit-symbolic icon
778188 TE crashes on multiple repeated BELL chars
780938 No icon tooltip shown in GtkEntry
781246 Return value of gtk_widget_get_parent_window should be marked (nullable)
783343 wayland: RFC - add shortcut inhibitor support
783906 gtk_accelerator_get_label broken
784016 Crash in gnome-terminal due to calling a GdkDisplayClass vfunc on a ...
784624 process-stop-symbolic hardcoded as app menu fallback
785280 GtkCenterBox: No G_BEGIN_DECLS and G_END_DECLS in gtkcenterbox.h
785318 GtkActionBar: g_object_class_install_properties() is not called
785375 Cursors for Wacom tablets are not always updated correctly under Wayland
785423 Missing nullable annotation for gtk_bin_get_child
785672 Entry: Setting icon tooltip to empty disables tooltip on whole widget
785793 gsk_color_matrix_node_draw leaking cairo_pattern_t
* Translation updates:
Croatian
Czech
Friulian
Indonesian
Punjabi
Slovenian
Spanish
Overview of Changes in GTK+ 3.91.1
==================================
* Redo event delivery and focus handling and grabs, and stop using
subwindows for widgets. API changes due to this include:
- a new GtkWidget::pick vfunc
- drop event mask apis
- drop windows from gestures
* The prelight state is now automatically set on widgets
* New widget: GtkCenterBox. This widget provides the center child
functionality that used to be part of GtkBox
* Wayland
- Improve the key repeat implementation
- Set vid/pid on tablet devices
* OS X:
- Add native file chooser support
* Bugs fixed:
745289 wayland: do not use g_error() on connection errors
759308 Instant apply in printing dialog (number of copies)
766517 GtkAboutDialog should use https:// license URLs
770513 MainToolbar in full-screen mode has rounded corners, which show video pix...
772281 Quartz backend: gtk_clipboard_get_selection not implemented
773299 Ensure GTK+-4.x builds and works on Windows (MSVC in particular)
775636 "New folder" creation popover warnings about trailing spaces flashes in...
781285 Key repeat cancel under Wayland should depend on which key is repeating
781583 gtk_image_new_from_resource does not work
781935 Add nullable return annotation to gtk_notebook_get_tab_label
781945 SIGSEGV dragging window on Wayland when toplevel window set_transient_for...
782040 Wacom pen calibration application responds to mouse input
782283 Wayland: Crash when dismissing a menu when a tooltip is visible
783047 Many apps crash in gdk_event_source_prepare when logging out of GNOME
783347 gtkfilechoosernativewin32: Fix support for non-ASCII paths
783397 Remove unused code in gtktextdisplay.c
783445 Incomplete documentation of gtk_widget_insert_after/before()
783587 Crash when NULL is passed to GtkActionHelper to unset action-name
784323 Quartz backend: gtk_clipboard_get_default not implemented
784723 macOS: native file chooser dialog
784888 gtkapplication: Mark gtk_application_get_active_window() as nullable
* Translation updates:
Catalan
Czech
Friulian
Hebrew
Kazakh
Norwegian bokmål
Spanish
Overview of Changes in GTK+ 3.91.0
==================================
+2 -2
View File
@@ -10,7 +10,7 @@
m4_define([gtk_major_version], [3])
m4_define([gtk_minor_version], [91])
m4_define([gtk_micro_version], [2])
m4_define([gtk_micro_version], [0])
m4_define([gtk_interface_age], [0])
m4_define([gtk_binary_age],
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
@@ -60,7 +60,7 @@ m4_define([cairo_required_version], [1.14.0])
m4_define([gdk_pixbuf_required_version], [2.30.0])
m4_define([introspection_required_version], [1.39.0])
m4_define([wayland_required_version], [1.9.91])
m4_define([wayland_protocols_required_version], [1.9])
m4_define([wayland_protocols_required_version], [1.7])
m4_define([mirclient_required_version], [0.22.0])
m4_define([mircookie_required_version], [0.17.0])
m4_define([epoxy_required_version], [1.0])
-1
View File
@@ -28,7 +28,6 @@ demos_base = \
expander.c \
filtermodel.c \
fishbowl.c \
widgetbowl.c \
foreigndrawing.c \
gestures.c \
glarea.c \
+3 -6
View File
@@ -455,15 +455,12 @@ demo_application_window_constructed (GObject *object)
}
static void
demo_application_window_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
demo_application_window_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
baseline, out_clip);
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation);
if (!window->maximized && !window->fullscreen)
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);
+29 -25
View File
@@ -207,7 +207,7 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *vbox, *hbox;
GtkWidget *label;
GtkWidget *entry, *button;
GtkWidget *image;
GtkWidget *ebox, *image;
GtkClipboard *clipboard;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
@@ -268,49 +268,53 @@ do_clipboard (GtkWidget *do_widget)
/* Create the first image */
image = gtk_image_new_from_icon_name ("dialog-warning",
GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (hbox), image);
ebox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (ebox), image);
gtk_container_add (GTK_CONTAINER (hbox), ebox);
/* make image a drag source */
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (image);
g_signal_connect (image, "drag-begin",
/* make ebox a drag source */
gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (ebox);
g_signal_connect (ebox, "drag-begin",
G_CALLBACK (drag_begin), image);
g_signal_connect (image, "drag-data-get",
g_signal_connect (ebox, "drag-data-get",
G_CALLBACK (drag_data_get), image);
/* accept drops on image */
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
/* accept drops on ebox */
gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL,
NULL, 0, GDK_ACTION_COPY);
gtk_drag_dest_add_image_targets (image);
g_signal_connect (image, "drag-data-received",
gtk_drag_dest_add_image_targets (ebox);
g_signal_connect (ebox, "drag-data-received",
G_CALLBACK (drag_data_received), image);
/* context menu on image */
g_signal_connect (image, "button-press-event",
/* context menu on ebox */
g_signal_connect (ebox, "button-press-event",
G_CALLBACK (button_press), image);
/* Create the second image */
image = gtk_image_new_from_icon_name ("process-stop",
GTK_ICON_SIZE_BUTTON);
gtk_container_add (GTK_CONTAINER (hbox), image);
ebox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (ebox), image);
gtk_container_add (GTK_CONTAINER (hbox), ebox);
/* make image a drag source */
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (image);
g_signal_connect (image, "drag-begin",
/* make ebox a drag source */
gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (ebox);
g_signal_connect (ebox, "drag-begin",
G_CALLBACK (drag_begin), image);
g_signal_connect (image, "drag-data-get",
g_signal_connect (ebox, "drag-data-get",
G_CALLBACK (drag_data_get), image);
/* accept drops on image */
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
/* accept drops on ebox */
gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL,
NULL, 0, GDK_ACTION_COPY);
gtk_drag_dest_add_image_targets (image);
g_signal_connect (image, "drag-data-received",
gtk_drag_dest_add_image_targets (ebox);
g_signal_connect (ebox, "drag-data-received",
G_CALLBACK (drag_data_received), image);
/* context menu on image */
g_signal_connect (image, "button-press-event",
/* context menu on ebox */
g_signal_connect (ebox, "button-press-event",
G_CALLBACK (button_press), image);
/* tell the clipboard manager to make the data persistent */
-1
View File
@@ -156,7 +156,6 @@
<file>expander.c</file>
<file>filtermodel.c</file>
<file>fishbowl.c</file>
<file>widgetbowl.c</file>
<file>flowbox.c</file>
<file>foreigndrawing.c</file>
<file>font_features.c</file>
+8 -9
View File
@@ -140,9 +140,6 @@ update_axes_from_event (GdkEvent *event,
return;
}
if (!source_device)
return;
if (!sequence)
{
info = g_hash_table_lookup (data->pointer_info, device);
@@ -617,7 +614,7 @@ do_event_axes (GtkWidget *toplevel)
{
static GtkWidget *window = NULL;
EventData *event_data;
GtkWidget *label;
GtkWidget *box, *label;
if (!window)
{
@@ -628,20 +625,22 @@ do_event_axes (GtkWidget *toplevel)
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_set_support_multidevice (window, TRUE);
box = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER (window), box);
gtk_widget_set_support_multidevice (box, TRUE);
event_data = event_data_new ();
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
g_object_set_data_full (G_OBJECT (box), "gtk-demo-event-data",
event_data, (GDestroyNotify) event_data_free);
g_signal_connect (window, "event",
g_signal_connect (box, "event",
G_CALLBACK (event_cb), event_data);
g_signal_connect (window, "draw",
g_signal_connect (box, "draw",
G_CALLBACK (draw_cb), event_data);
label = gtk_label_new ("");
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_container_add (GTK_CONTAINER (window), label);
gtk_container_add (GTK_CONTAINER (box), label);
init_pad_controller (window, label);
}
-1
View File
@@ -157,7 +157,6 @@ do_fishbowl (GtkWidget *do_widget)
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
gtk_window_set_screen (GTK_WINDOW (window),
+1
View File
@@ -10,6 +10,7 @@
<child>
<object class="GtkLabel" id="info_label">
<property name="visible">True</property>
<property name="label">icons - 0 fps</property>
</object>
<packing>
<property name="pack_type">end</property>
+10 -5
View File
@@ -1601,13 +1601,18 @@
<property name="margin_top">20</property>
<property name="margin_bottom">20</property>
<child>
<object class="GtkLabel" id="label">
<object class="GtkEventBox">
<property name="visible">1</property>
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<signal name="button-press-event" handler="switch_to_entry"/>
<child>
<object class="GtkLabel" id="label">
<property name="visible">1</property>
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
</object>
</child>
</object>
<packing>
<property name="name">label</property>
+31 -44
View File
@@ -29,8 +29,6 @@ struct _GtkFishbowlPrivate
gint64 last_frame_time;
guint tick_id;
guint use_icons: 1;
};
struct _GtkFishbowlChild
@@ -72,15 +70,6 @@ gtk_fishbowl_new (void)
return g_object_new (GTK_TYPE_FISHBOWL, NULL);
}
void
gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
gboolean use_icons)
{
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
priv->use_icons = use_icons;
}
static void
gtk_fishbowl_measure (GtkWidget *widget,
GtkOrientation orientation,
@@ -114,10 +103,8 @@ gtk_fishbowl_measure (GtkWidget *widget,
}
static void
gtk_fishbowl_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_fishbowl_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
@@ -126,10 +113,10 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
GtkRequisition child_requisition;
GList *children;
gtk_widget_set_allocation (widget, allocation);
for (children = priv->children; children; children = children->next)
{
GtkAllocation child_clip;
child = children->data;
if (!gtk_widget_get_visible (child->widget))
@@ -141,7 +128,7 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
child_allocation.width = child_requisition.width;
child_allocation.height = child_requisition.height;
gtk_widget_size_allocate (child->widget, &child_allocation, -1, &child_clip);
gtk_widget_size_allocate (child->widget, &child_allocation);
}
}
@@ -231,6 +218,27 @@ gtk_fishbowl_forall (GtkContainer *container,
}
}
static void
gtk_fishbowl_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
GtkFishbowlChild *child;
GList *list;
for (list = priv->children;
list;
list = list->next)
{
child = list->data;
gtk_widget_snapshot_child (widget,
child->widget,
snapshot);
}
}
static void
gtk_fishbowl_dispose (GObject *object)
{
@@ -303,6 +311,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
widget_class->measure = gtk_fishbowl_measure;
widget_class->size_allocate = gtk_fishbowl_size_allocate;
widget_class->snapshot = gtk_fishbowl_snapshot;
container_class->add = gtk_fishbowl_add;
container_class->remove = gtk_fishbowl_remove;
@@ -373,25 +382,6 @@ get_random_icon_name (GtkIconTheme *theme)
return icon_names[g_random_int_range(0, n_icon_names)];
}
static GType
get_random_widget_type ()
{
GType types[] = {
GTK_TYPE_SWITCH,
GTK_TYPE_BUTTON,
GTK_TYPE_ENTRY,
GTK_TYPE_SPIN_BUTTON,
GTK_TYPE_FONT_BUTTON,
GTK_TYPE_SCROLLBAR,
GTK_TYPE_SCALE,
GTK_TYPE_LEVEL_BAR,
GTK_TYPE_PROGRESS_BAR,
GTK_TYPE_RADIO_BUTTON,
GTK_TYPE_CHECK_BUTTON
};
return types[g_random_int_range (0, G_N_ELEMENTS (types))];
}
void
gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count)
@@ -409,13 +399,10 @@ gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
while (priv->count < count)
{
GtkWidget *new_widget;
if (priv->use_icons)
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
GTK_ICON_SIZE_DIALOG);
else
new_widget = g_object_new (get_random_widget_type (), NULL);
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()),
GTK_ICON_SIZE_DIALOG);
gtk_widget_show (new_widget);
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
}
-3
View File
@@ -46,9 +46,6 @@ GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_fishbowl_new (void);
void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
gboolean use_icons);
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
guint count);
-1
View File
@@ -25,7 +25,6 @@ demos = files([
'expander.c',
'filtermodel.c',
'fishbowl.c',
'widgetbowl.c',
'foreigndrawing.c',
'gestures.c',
'glarea.c',
+2 -4
View File
@@ -55,10 +55,8 @@ create_complex_popover (GtkWidget *parent,
}
static void
entry_size_allocate_cb (GtkEntry *entry,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
entry_size_allocate_cb (GtkEntry *entry,
GtkAllocation *allocation,
gpointer user_data)
{
GtkEntryIconPosition popover_pos;
+9 -9
View File
@@ -19,7 +19,7 @@ hex_spin_input (GtkSpinButton *spin_button,
gchar *err;
gdouble res;
buf = gtk_spin_button_get_text (spin_button);
buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
res = strtol (buf, &err, 16);
*new_val = res;
if (*err)
@@ -41,8 +41,8 @@ hex_spin_output (GtkSpinButton *spin_button)
buf = g_strdup ("0x00");
else
buf = g_strdup_printf ("0x%.2X", val);
if (strcmp (buf, gtk_spin_button_get_text (spin_button)))
gtk_spin_button_set_text (spin_button, buf);
if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
g_free (buf);
return TRUE;
@@ -60,7 +60,7 @@ time_spin_input (GtkSpinButton *spin_button,
gchar *endh;
gchar *endm;
text = gtk_spin_button_get_text (spin_button);
text = gtk_entry_get_text (GTK_ENTRY (spin_button));
str = g_strsplit (text, ":", 2);
if (g_strv_length (str) == 2)
@@ -99,8 +99,8 @@ time_spin_output (GtkSpinButton *spin_button)
hours = gtk_adjustment_get_value (adjustment) / 60.0;
minutes = (hours - floor (hours)) * 60.0;
buf = g_strdup_printf ("%02.0f:%02.0f", floor (hours), floor (minutes + 0.5));
if (strcmp (buf, gtk_spin_button_get_text (spin_button)))
gtk_spin_button_set_text (spin_button, buf);
if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
g_free (buf);
return TRUE;
@@ -132,7 +132,7 @@ month_spin_input (GtkSpinButton *spin_button,
for (i = 1; i <= 12; i++)
{
tmp1 = g_ascii_strup (month[i - 1], -1);
tmp2 = g_ascii_strup (gtk_spin_button_get_text (spin_button), -1);
tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
if (strstr (tmp1, tmp2) == tmp1)
found = TRUE;
g_free (tmp1);
@@ -162,8 +162,8 @@ month_spin_output (GtkSpinButton *spin_button)
for (i = 1; i <= 12; i++)
if (fabs (value - (double)i) < 1e-5)
{
if (strcmp (month[i-1], gtk_spin_button_get_text (spin_button)))
gtk_spin_button_set_text (spin_button, month[i-1]);
if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
}
return TRUE;
-179
View File
@@ -1,179 +0,0 @@
/* Benchmark/Widgetbowl
*
* This demo models the fishbowl demos seen on the web in a GTK way.
* It's also a neat little tool to see how fast your computer (or
* your GTK version) is.
*/
#include <gtk/gtk.h>
#include "gtkfishbowl.h"
GtkWidget *allow_changes;
#define N_STATS 5
#define STATS_UPDATE_TIME G_USEC_PER_SEC
typedef struct _Stats Stats;
struct _Stats {
gint64 last_stats;
gint64 last_frame;
gint last_suggestion;
guint frame_counter_max;
guint stats_index;
guint frame_counter[N_STATS];
guint item_counter[N_STATS];
};
static Stats *
get_stats (GtkWidget *widget)
{
static GQuark stats_quark = 0;
Stats *stats;
if (G_UNLIKELY (stats_quark == 0))
stats_quark = g_quark_from_static_string ("stats");
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
if (stats == NULL)
{
stats = g_new0 (Stats, 1);
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
stats->last_stats = stats->last_frame;
}
return stats;
}
static void
do_stats (GtkWidget *widget,
GtkWidget *info_label,
gint *suggested_change)
{
Stats *stats;
gint64 frame_time;
stats = get_stats (widget);
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
{
char *new_label;
guint i, n_frames;
n_frames = 0;
for (i = 0; i < N_STATS; i++)
{
n_frames += stats->frame_counter[i];
}
new_label = g_strdup_printf ("widgets - %.1f fps",
(double) G_USEC_PER_SEC * n_frames
/ (N_STATS * STATS_UPDATE_TIME));
gtk_label_set_label (GTK_LABEL (info_label), new_label);
g_free (new_label);
if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
{
if (stats->last_suggestion > 0)
stats->last_suggestion *= 2;
else
stats->last_suggestion = 1;
}
else
{
if (stats->last_suggestion < 0)
stats->last_suggestion--;
else
stats->last_suggestion = -1;
stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) stats->item_counter[stats->stats_index]);
}
stats->stats_index = (stats->stats_index + 1) % N_STATS;
stats->frame_counter[stats->stats_index] = 0;
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
stats->last_stats = frame_time;
if (suggested_change)
*suggested_change = stats->last_suggestion;
else
stats->last_suggestion = 0;
}
else
{
if (suggested_change)
*suggested_change = 0;
}
stats->last_frame = frame_time;
stats->frame_counter[stats->stats_index]++;
stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
}
static void
stats_update (GtkWidget *widget)
{
Stats *stats;
stats = get_stats (widget);
stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
}
static gboolean
move_fish (GtkWidget *bowl,
GdkFrameClock *frame_clock,
gpointer info_label)
{
gint suggested_change = 0;
do_stats (bowl,
info_label,
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
gtk_fishbowl_set_count (GTK_FISHBOWL (bowl),
gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change);
stats_update (bowl);
return G_SOURCE_CONTINUE;
}
GtkWidget *
do_widgetbowl (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
GtkWidget *bowl, *info_label;
g_type_ensure (GTK_TYPE_FISHBOWL);
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
gtk_builder_connect_signals (builder, NULL);
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), FALSE);
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
gtk_window_set_screen (GTK_WINDOW (window),
gtk_widget_get_screen (do_widget));
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed), &window);
gtk_widget_realize (window);
gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_widget_destroy (window);
return window;
}
+1 -2
View File
@@ -32,8 +32,7 @@ resources.c: iconbrowser.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourc
EXTRA_DIST = \
menus.ui \
iconbrowser.gresource.xml \
window.ui \
icon.list
window.ui
# ------------------- MSVC Build Items ----------------
MSVCPROJS = gtk4-icon-browser
-517
View File
@@ -1,517 +0,0 @@
[volume]
Name=Volume
Description=Icons related to audio input and output volume
audio-volume-high=The icon used to indicate high audio volume
audio-volume-low=The icon used to indicate low audio volume
audio-volume-medium=The icon used to indicate medium audio volume
audio-volume-muted=The icon used to indicate the muted state for audio playback
microphone-sensitivity-high=The icon used to indicate high microphone sensitivity
microphone-sensitivity-low=The icon used to indicate low microphone sensitivity
microphone-sensitivity-medium=The icon used to indicate medium microphone sensitivity
microphone-sensitivity-muted=The icon used to indicate that a microphone is muted
[multimedia]
Name=Multimedia
Description=Icons related to playback of media
media-playlist-repeat=The icon for the repeat mode of a media player
media-playlist-repeat-song=The icon for repeating a song in a media player
media-playlist-shuffle=The icon for the shuffle mode of a media player
media-playlist-consecutive=The icon for consecutive mode of a media player
media-skip-backward=The icon for the skip backward action of a media player
media-seek-backward=The icon for the seek backward action of a media player
media-playback-start=The icon for the start playback action of a media player
media-seek-forward=The icon for the seek forward action of a media player
media-skip-forward=The icon for the skip forward action of a media player
media-playback-stop=The icon for the stop action of a media player
media-playback-pause=The icon for the pause action of a media player
media-eject=The icon for the eject action of a media player or file manager
media-record=The icon for the record action of a media application
media-view-subtitles=The icon used to show subtitles in a media player
[network]
Name=Network
Description=Icons related to network status");
network-transmit-receive=The icon used data is being both transmitted and received simultaneously, while the computing device is connected to a network
network-transmit=The icon used when data is being transmitted, while the computing device is connected to a network
network-receive=The icon used when data is being received, while the computing device is connected to a network
network-idle=The icon used when no data is being transmitted or received, while the computing device is connected to a network
network-error=The icon used when an error occurs trying to intialize the network connection of the computing device
network-offline=The icon used when the computing device is disconnected from the network
[weather]
Name=Weather
Description=Icons about weather conditions
weather-clear=The icon used while the weather for a region is “clear skies”
weather-clear-night=The icon used while the weather for a region is “clear skies” during the night
weather-few-clouds=The icon used while the weather for a region is “partly cloudy”
weather-few-clouds-night=The icon used while the weather for a region is “partly cloudy” during the night
weather-fog=The icon used while the weather for a region is “foggy”
weather-overcast=The icon used while the weather for a region is “overcast”
weather-severe-alert=The icon used while a sever weather alert is in effect for a region
weather-showers=The icon used while rain showers are occurring in a region
weather-showers-scattered=The icon used while scattered rain showers are occurring in a region
weather-snow=The icon used while snow showers are occurring in a region
weather-storm=The icon used while storms are occurring in a region
weather-windy=The icon used while the weather is windy
[navigation]
Name=Navigation
Description=Icons for navigation in the user interface of a program
go-first=The icon for the go to the first item in a list
go-previous=The icon for the go to the previous item in a list
go-next=The icon for the go to the next item in a list
go-last=The icon for the go to the last item in a list
go-bottom=The icon for the go to bottom of a list
go-down=The icon for the go down in a list
go-up=The icon for the go up in a list
go-top=The icon for the go to the top of a list
go-home=The icon for the go to home location
go-jump=The icon for the jump to action
[editing]
Name=Editing
Description=Icons related to editing a document
format-indent-less=The icon for the decrease indent formatting action
format-indent-more=The icon for the increase indent formatting action
format-justify-center=The icon for the center justification formatting action
format-justify-fill=The icon for the fill justification formatting action
format-justify-left=The icon for the left justification formatting action
format-justify-right=The icon for the right justification action
format-text-direction-ltr=The icon for the left-to-right text formatting action
format-text-direction-rtl=The icon for the right-to-left formatting action
format-text-bold=The icon for the bold text formatting action
format-text-italic=The icon for the italic text formatting action
format-text-underline=The icon for the underlined text formatting action
format-text-strikethrough=The icon for the strikethrough text formatting action
edit-clear=The icon for the clear action
edit-clear-all=
edit-copy=The icon for the copy action
edit-cut=The icon for the cut action
edit-delete=The icon for the delete action
edit-find-replace=The icon for the find and replace action
edit-paste=The icon for the paste action
edit-redo=The icon for the redo action
edit-select-all=The icon for the select all action
edit-select=
edit-undo=The icon for the undo action
error-correct=
document-properties=The icon for the action to view the properties of a document in an application
document-new=The icon used for the action to create a new document
document-open=The icon used for the action to open a document
document-open-recent=The icon used for the action to open a document that was recently opened
document-save=The icon for the save action. Should be an arrow pointing down and toward a hard disk
document-save-as=The icon for the save as action
document-send=The icon for the send action. Should be an arrow pointing up and away from a hard disk
document-page-setup=The icon for the page setup action of a document editor
document-edit=The icon for the action to edit a document
object-flip-horizontal=The icon for the action to flip an object horizontally
object-flip-vertical=The icon for the action to flip an object vertically
object-rotate-left=The icon for the rotate left action performed on an object
object-rotate-right=The icon for the rotate rigt action performed on an object
insert-image=The icon for the insert image action of an application
insert-link=The icon for the insert link action of an application
insert-object=The icon for the insert object action of an application
insert-text=The icon for the insert text action of an application
accessories-text-editor=The icon used for the desktop's text editing accessory program
[view]
Name=View Controls
Description=Icons for view controls in a user interface
view-list=The icon used for “List“ view mode
view-grid=The icon used for “Grid“ view mode (as opposed to “List“)
view-fullscreen=The icon used for the “Fullscreen” item in the application's “View” menu
view-restore=The icon used by an application for leaving the fullscreen view, and returning to a normal windowed view
zoom-fit-best=The icon used for the “Best Fit” item in the application's “View” menu
zoom-in=The icon used for the “Zoom in” item in the application's “View” menu
zoom-out=The icon used for the “Zoom Out” item in the application's “View” menu
zoom-original=The icon used for the “Original Size” item in the application's “View” menu
view-continuous=The icon used for a continuous view mode
view-paged=The icon used for a paged view mode (as opposed to continuous)
view-dual=The icon used for a side-by-side view of paginated content
view-wrapped=The icon used to indicate a wrap-around to the beginning
view-pin=The icon used for 'pin a view'
[calendar]
Name=Calendar, Tasks and Alarms
Description=Icons related to calendars, tasks and alarms
task-due=The icon used when a task is due soon
task-past-due=The icon used when a task that was due, has been left incomplete
appointment-soon=The icon used when an appointment will occur soon
appointment-missed=The icon used when an appointment was missed
alarm=The icon used for alarms when a task or appointment is due
[communication]
Name=Communication
Description=Icons related email, phone calls, IM and other forms of communication
mail-unread=The icon used for an electronic mail that is unread
mail-read=The icon used for an electronic mail that is read
mail-replied=The icon used for an electronic mail that has been replied to
mail-attachment=The icon used for an electronic mail that contains attachments
mail-mark-important=The icon for the mark as important action of an electronic mail application
mail-send=The icon for the send action of an electronic mail application
mail-send-receive=The icon for the send and receive action of an electronic mail application
call-start=The icon used for initiating or accepting a call
call-stop=The icon used for stopping a current call
call-missed=The icon used to show a missed call
user-available=The icon used when a user on a chat network is available to initiate a conversation with
user-offline=The icon used when a user on a chat network is not available
user-idle=The icon used when a user on a chat network has not been an active participant in any chats on the network, for an extended period of time
user-invisible=The icon used when a user is on a chat network, but is invisible to others
user-busy=The icon used when a user is on a chat network, and has marked himself as busy
user-away=The icon used when a user on a chat network is away from their keyboard and the chat program
user-status-pending=The icon used when the current user status on a chat network is not known
[devices]
Name=Devices and Media
Description=Icons for devices and media
audio-input-microphone=The icon used for the microphone audio input device
camera-web=The fallback icon for web cameras
camera-photo=The icon used for a digital still camera devices
input-keyboard=The icon used for the keyboard input device
printer=The icon used for a printer device
video-display=The icon used for the monitor that video gets displayed to
computer=The icon used for the computing device as a whole
media-optical=The icon used for physical optical media such as CD and DVD
phone=The icon used for phone devices which support connectivity to the PC, such as VoIP, cellular, or possibly landline phones
input-dialpad=The icon used for dialpad input devices
input-touchpad=The icon used for touchpad input devices
scanner=The icon used for a scanner device
audio-card=The icon used for the audio rendering device
input-gaming=The icon used for the gaming input device
input-mouse=The icon used for the mousing input device
multimedia-player=The icon used for generic multimedia playing devices
audio-headphones=The icon used for headphones
audio-headset=The icon used for headsets
display-projector=The icon used for projectors
media-removable=The icon used for generic removable media
printer-network=The icon used for printers which are connected via the network
audio-speakers=The icon used for speakers
camera-video=The fallback icon for video cameras
drive-optical=The icon used for optical media drives such as CD and DVD
drive-removable-media=The icon used for removable media drives
input-tablet=The icon used for graphics tablet input devices
network-wireless=The icon used for wireless network connections
network-wired=The icon used for wired network connections
media-floppy=The icon used for physical floppy disk media
media-flash=The fallback icon used for flash media, such as memory stick and SD
[contenttypes]
Name=Content Types
Description=Icons for different types of data, such as audio or image files
application-certificate=
application-rss+xml=
application-x-appliance=
audio-x-generic=The icon used for generic audio file types
folder=The standard folder icon used to represent directories on local filesystems, mail folders, and other hierarchical groups
text-x-generic=The icon used for generic text file types
video-x-generic=The icon used for generic video file types
x-office-calendar=The icon used for generic calendar file types
[emotes]
Name=Emotes
Description=Icons for emotions that are expressed through text chat applications such as :-) or :-P in IRC or instant messengers
face-angel=The icon used for the 0:-) emote
face-angry=The icon used for the X-( emote
face-cool=The icon used for the B-) emote
face-crying=The icon used for the :'( emote
face-devilish=The icon used for the >:-) emote
face-embarrassed=The icon used for the :-[ emote
face-kiss=The icon used for the :-* emote
face-laugh=The icon used for the :-)) emote
face-monkey=The icon used for the :-(|) emote
face-plain=The icon used for the :-| emote
face-raspberry=The icon used for the :-P emote
face-sad=The icon used for the :-( emote
face-shutmouth=The 'shut mouth' emote
face-sick=The icon used for the :-& emote
face-smile=The icon used for the :-) emote
face-smile-big=The icon used for the :-D emote
face-smirk=The icon used for the :-! emote
face-surprise=The icon used for the :-0 emote
face-tired=The icon used for the |-) emote
face-uncertain=The icon used for the :-/ emote
face-wink=The icon used for the ;-) emote
face-worried=The icon used for the :-S emote
face-yawn=
[general]
Name=General
Description=Generally useful icons that don't fit in a particular category
edit-find=The icon for generic search actions
content-loading=The icon used to indicate that content is loading
open-menu=The icon used for a menu button in the header bar
view-more=The icon used for a “View More“ action
tab-new=The icon used for a “New Tab“ action
bookmark-new=The icon used for creating a new bookmark
mark-location=The icon used to mark a location on a map
find-location=The icon used for a “Search location“ action
send-to=The icon used for a “Send to“ action
object-select=The icon used for generic selection actions
window-close=The icon used for actions that close a view, such as window or tab close button
view-refresh=The icon used for the “Refresh” item in the application's “View” menu
process-stop=The icon used for the “Stop” action in applications with actions that may take a while to process, such as web page loading in a browser
action-unavailable=The icon used to indicate that an action is currently unavailable, such as “Pause“ when no media is playing
document-print=The icon for the print action of an application
printer-printing=The icon used while a print job is successfully being spooled to a printing device
printer-warning=The icon used when a recoverable problem occurs while attempting to printing
printer-error=The icon used when an error occurs while attempting to print
dialog-information=The icon used when a dialog is opened to give information to the user that may be pertinent to the requested action
dialog-question=The icon used when a dialog is opened to ask a simple question of the user
dialog-warning=The icon used when a dialog is opened to warn the user of impending issues with the requested action
dialog-password=The icon used when a dialog requesting the authentication credentials for a user is opened
dialog-error=The icon used when a dialog is opened to explain an error condition to the user
list-add=The icon for the add to list action
list-remove=The icon for the remove from list action
non-starred=The icon used to indicate that an object is not 'starred'
semi-starred=The icon used to indicate that an object has is 'half-starred'
starred=The icon used to indicate that an object is 'starred'
star-new=The used for the “New Star“ action
security-low=The icon used to indicate that the security level of a connection is presumed to be insecure, either by using weak encryption, or by using a certificate that the could not be automatically verified, and which the user has not chosent to trust
security-medium=The icon used to indicate that the security level of a connection is presumed to be secure, using strong encryption, and a certificate that could not be automatically verified, but which the user has chosen to trust
security-high=The icon used to indicate that the security level of a connection is known to be secure, using strong encryption and a valid certificate
user-trash=The icon for the user's “Trash” place in the file system
user-trash-full=The icon for the user's “Trash” in the file system, when there are items in the “Trash” waiting for disposal or recovery
emblem-system=The icon used as an emblem for directories that contain system libraries, settings, and data
avatar-default=The generic avatar icon, which is used to represent a user that doesn't have a personalized avatar
emblem-synchronizing=The icon used as an emblem to indicate that a a synchronizing operation is in process
emblem-shared=The icon used as an emblem for files and directories that are shared to other users
folder-download=The icon representing the location in the file system where downloaded files are stored
help-browser=The icon used for the desktop's help browsing application
[other]
Name=Other
Description=Icons which have may be too specialized and not of general interest
changes-allow=
changes-prevent=
view-sort-ascending=The icon used for the “Sort Ascending” item in the application's “View” menu, or in a button for changing the sort method for a list
view-sort-descending=The icon used for the “Sort Descending” item in the application's “View” menu, or in a button for changing the sort method for a list
document-revert=The icon for the action of reverting to a previous version of a document
address-book-new=The icon used for the action to create a new address book
application-exit=The icon used for exiting an application. Typically this is seen in the application's menus as File->Quit
appointment-new=The icon used for the action to create a new appointment in a calendaring application
contact-new=The icon used for the action to create a new contact in an address book application
document-print-preview=The icon for the print preview action of an application
folder-new=The icon for creating a new folder
help-about=The icon for the About item in the Help menu
help-contents=The icon for Contents item in the Help menu
help-faq=The icon for the FAQ item in the Help menu
list-remove-all=
mail-forward=The icon for the forward action of an electronic mail application
mail-mark-junk=The icon for the mark as junk action of an electronic mail application
mail-mark-notjunk=The icon for the mark as not junk action of an electronic mail application
mail-mark-read=The icon for the mark as read action of an electronic mail application
mail-mark-unread=The icon for the mark as unread action of an electronic mail application
mail-message-new=The icon for the compose new mail action of an electronic mail application
mail-reply-all=The icon for the reply to all action of an electronic mail application
mail-reply-sender=The icon for the reply to sender action of an electronic mail application
pan-down=
pan-end=
pan-start=
pan-up=
system-lock-screen=The icon used for the “Lock Screen” item in the desktop's panel application
system-log-out=The icon used for the “Log Out” item in the desktop's panel application
system-run=The icon used for the “Run Application...” item in the desktop's panel application
system-search=The icon used for the “Search” item in the desktop's panel application
system-reboot=The icon used for the “Reboot” item in the desktop's panel application
system-shutdown=The icon used for the “Shutdown” item in the desktop's panel application
tools-check-spelling=The icon used for the “Check Spelling” item in the application's “Tools” menu
window-maximize=
window-minimize=
window-restore=
window-new=The icon used for the “New Window” item in the application's “Windows” menu
accessories-calculator=The icon used for the desktop's calculator accessory program
accessories-character-map=The icon used for the desktop's international and extended text character accessory program
accessories-dictionary=The icon used for the desktop's dictionary accessory program
multimedia-volume-control=The icon used for the desktop's hardware volume control application
preferences-desktop-accessibility=The icon used for the desktop's accessibility preferences
preferences-desktop-display=
preferences-desktop-font=The icon used for the desktop's font preferences
preferences-desktop-keyboard=The icon used for the desktop's keyboard preferences
preferences-desktop-keyboard-shortcuts=
preferences-desktop-locale=The icon used for the desktop's locale preferences
preferences-desktop-remote-desktop=
preferences-desktop-multimedia=The icon used for the desktop's multimedia preferences
preferences-desktop-screensaver=The icon used for the desktop's screen saving preferences
preferences-desktop-theme=The icon used for the desktop's theme preferences
preferences-desktop-wallpaper=The icon used for the desktop's wallpaper preferences
preferences-system-privacy=
preferences-system-windows=
system-file-manager=The icon used for the desktop's file management application
system-software-install=The icon used for the desktop's software installer application
system-software-update=The icon used for the desktop's software updating application
system-users=
user-info=
utilities-system-monitor=The icon used for the desktop's system resource monitor application
utilities-terminal=The icon used for the desktop's terminal emulation application.
application-x-addon=
application-x-executable=The icon used for executable file types
font-x-generic=The icon used for generic font file types
image-x-generic=The icon used for generic image file types
package-x-generic=The icon used for generic package file types
text-html=The icon used for HTML text file types
text-x-generic-template=The icon used for generic text templates
text-x-preview=
text-x-script=The icon used for script file types, such as shell scripts
x-office-address-book=The icon used for generic address book file types
x-office-document=The icon used for generic document and letter file types
x-office-document-template=
x-office-presentation=The icon used for generic presentation file types
x-office-presentation-template=
x-office-spreadsheet=The icon used for generic spreadsheet file types
x-office-spreadsheet-template=
x-package-repository=
applications-accessories=The icon for the “Accessories” sub-menu of the Programs menu
applications-development=The icon for the “Programming” sub-menu of the Programs menu
applications-engineering=The icon for the “Engineering” sub-menu of the Programs menu
applications-games=The icon for the “Games” sub-menu of the Programs menu
applications-graphics=The icon for the “Graphics” sub-menu of the Programs menu
applications-internet=The icon for the “Internet” sub-menu of the Programs menu
applications-multimedia=The icon for the “Multimedia” sub-menu of the Programs menu
applications-office=The icon for the “Office” sub-menu of the Programs menu
applications-other=The icon for the “Other” sub-menu of the Programs menu
applications-science=The icon for the “Science” sub-menu of the Programs menu
applications-system=The icon for the “System Tools” sub-menu of the Programs menu
applications-utilities=The icon for the “Utilities” sub-menu of the Programs menu
preferences-desktop=The icon for the “Desktop Preferences” category
preferences-desktop-peripherals=The icon for the “Peripherals” sub-category of the “Desktop Preferences” category
preferences-desktop-personal=The icon for the “Personal” sub-category of the “Desktop Preferences” category
preferences-other=The icon for the “Other” preferences category
preferences-system=The icon for the “System Preferences” category
preferences-system-network=The icon for the “Network” sub-category of the “System Preferences” category
system-help=The icon for the “Help” system category
battery=The icon used for the system battery device
computer-apple-ipad=
colorimeter-colorhug=
drive-harddisk=The icon used for hard disk drives
drive-harddisk-ieee1394=
drive-harddisk-system=
drive-multidisk=
media-optical-bd=
media-optical-cd-audio=
media-optical-dvd=
media-tape=The icon used for generic physical tape media
media-zip=
modem=The icon used for modem devices
multimedia-player-apple-ipod-touch=
network-vpn=
pda=This is the fallback icon for Personal Digial Assistant devices. Primary use of this icon is for PDA devices connected to the PC. Connection medium is not an important aspect of the icon. The metaphor for this fallback icon should be a generic PDA device icon
phone-apple-iphone=
uninterruptible-power-supply=
emblem-default=The icon used as an emblem to specify the default selection of a printer for example
emblem-documents=The icon used as an emblem for the directory where a user's documents are stored
emblem-downloads=The icon used as an emblem for the directory where a user's downloads from the internet are stored
emblem-favorite=The icon used as an emblem for files and directories that the user marks as favorites
emblem-generic=
emblem-important=The icon used as an emblem for files and directories that are marked as important by the user
emblem-mail=The icon used as an emblem to specify the directory where the user's electronic mail is stored
emblem-new=
emblem-ok=
emblem-package=
emblem-photos=The icon used as an emblem to specify the directory where the user stores photographs
emblem-readonly=The icon used as an emblem for files and directories which can not be written to by the user
emblem-symbolic-link=The icon used as an emblem for files and direcotires that are links to other files or directories on the filesystem
emblem-synchronized=The icon used as an emblem for files or directories that are configured to be synchronized to another device
emblem-unreadable=The icon used as an emblem for files and directories that are inaccessible.
emblem-urgent=
emblem-videos=
emblem-web=
folder-documents=
folder-download=
folder-music=
folder-pictures=
folder-documents=
folder-publicshare=
folder-remote=The icon used for normal directories on a remote filesystem
folder-saved-search=
folder-templates=
folder-videos=
network-server=The icon used for individual host machines under the “Network Servers” place in the file manager
network-workgroup=The icon for the “Network Servers” place in the desktop's file manager, and workgroups within the network
start-here=The icon used by the desktop's main menu for accessing places, applications, and other features
user-bookmarks=The icon for the user's special “Bookmarks” place
user-desktop=The icon for the special “Desktop” directory of the user
user-home=The icon for the special “Home” directory of the user
airplane-mode=
battery-caution-charging=
battery-caution=The icon used when the battery is below 40%
battery-empty-charging=
battery-empty=
battery-full-charged=
battery-full-charging=
battery-full=
battery-good-charging=
battery-good=
battery-low-charging=
battery-low=The icon used when the battery is below 20%
battery-missing=
bluetooth-active=
bluetooth-disabled=
channel-insecure=
channel-secure=
computer-fail=
display-brightness=
keyboard-brightness=
folder-drag-accept=The icon used for a folder while an object is being dragged onto it, that is of a type that the directory can contain
folder-open=The icon used for folders, while their contents are being displayed within the same window. This icon would normally be shown in a tree or list view, next to the main view of a folder's contents
folder-visiting=The icon used for folders, while their contents are being displayed in another window. This icon would typically be used when using multiple windows to navigate the hierarchy, such as in Nautilus's spatial mode
image-loading=The icon used when another image is being loaded, such as thumnails for larger images in the file manager
image-missing=The icon used when another image could not be loaded
mail-signed=The icon used for an electronic mail that contains a signature
mail-signed-verified=The icon used for an electronic mail that contains a signature which has also been verified by the security system
network-cellular-3g=
network-cellular-4g=
network-cellular-edge=
network-cellular-gprs=
network-cellular-umts=
network-cellular-acquiring=
network-cellular-connected=
network-cellular-no-route=
network-cellular-offline=
network-cellular-signal-excellent=
network-cellular-signal-good=
network-cellular-signal-ok=
network-cellular-signal-weak=
network-cellular-signal-none=
network-vpn-acquiring=
network-vpn=
network-wired-acquiring=
network-wired-disconnected=
network-wired-no-route=
network-wired-offline=
network-wireless-acquiring=
network-wireless-connected=
network-wireless-encrypted=
network-wireless-hotspot=
network-wireless-no-route=
network-wireless-offline=
network-wireless-signal-excellent=
network-wireless-signal-good=
network-wireless-signal-ok=
network-wireless-signal-weak=
network-wireless-signal-none=
rotation-allowed=
rotation-locked=
software-update-available=The icon used when an update is available for software installed on the computing device, through the system software update program
software-update-urgent=The icon used when an urgent update is available through the system software update program
sync-error=The icon used when an error occurs while attempting to synchronize data from the computing device, to another device
sync-synchronizing=The icon used while data is successfully synchronizing to another device
touchpad-disabled=
trophy-bronze=
trophy-silver=
trophy-gold=
night-light=
daytime-sunrise=
daytime-sunset=
@@ -3,6 +3,5 @@
<gresource prefix="/org/gtk/iconbrowser/gtk">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">menus.ui</file>
<file>icon.list</file>
</gresource>
</gresources>
+477 -72
View File
@@ -6,22 +6,11 @@
typedef struct
{
gchar *id;
gchar *name;
gchar *description;
const gchar *id;
const gchar *name;
const gchar *description;
} Context;
static void
context_free (gpointer data)
{
Context *context = data;
g_free (context->id);
g_free (context->name);
g_free (context->description);
g_free (context);
}
struct _IconBrowserWindow
{
GtkApplicationWindow parent;
@@ -92,7 +81,7 @@ set_image (GtkWidget *image, const gchar *name, gint size)
gtk_image_set_from_icon_name (GTK_IMAGE (image), name, 1);
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
pixbuf = get_icon (image, name, size);
gtk_drag_source_set_icon_pixbuf (image, pixbuf);
gtk_drag_source_set_icon_pixbuf (gtk_widget_get_parent (image), pixbuf);
g_object_unref (pixbuf);
}
@@ -165,7 +154,6 @@ add_icon (IconBrowserWindow *win,
g_free (symbolic_name);
symbolic_name = NULL;
}
gtk_list_store_insert_with_values (win->store, NULL, -1,
ICON_STORE_NAME_COLUMN, regular_name,
ICON_STORE_SYMBOLIC_NAME_COLUMN, symbolic_name,
@@ -184,11 +172,11 @@ add_context (IconBrowserWindow *win,
GtkWidget *row;
c = g_new (Context, 1);
c->id = g_strdup (id);
c->name = g_strdup (name);
c->description = g_strdup (description);
c->id = id;
c->name = name;
c->description = description;
g_hash_table_insert (win->contexts, c->id, c);
g_hash_table_insert (win->contexts, (gpointer)id, c);
row = gtk_label_new (name);
g_object_set_data (G_OBJECT (row), "context", c);
@@ -225,50 +213,475 @@ selected_context_changed (GtkListBox *list, IconBrowserWindow *win)
static void
populate (IconBrowserWindow *win)
{
GFile *file;
GKeyFile *kf;
char *data;
gsize length;
char **groups;
int i;
add_context (win, "volume", "Volume", "Icons related to audio input and output volume");
add_icon (win, "audio-volume-high", "The icon used to indicate high audio volume", "volume");
add_icon (win, "audio-volume-low", "The icon used to indicate low audio volume", "volume");
add_icon (win, "audio-volume-medium", "The icon used to indicate medium audio volume", "volume");
add_icon (win, "audio-volume-muted", "The icon used to indicate the muted state for audio playback", "volume");
add_icon (win, "microphone-sensitivity-high", "The icon used to indicate high microphone sensitivity", "volume");
add_icon (win, "microphone-sensitivity-low", "The icon used to indicate low microphone sensitivity", "volume");
add_icon (win, "microphone-sensitivity-medium", "The icon used to indicate medium microphone sensitivity", "volume");
add_icon (win, "microphone-sensitivity-muted", "The icon used to indicate that a microphone is muted", "volume");
file = g_file_new_for_uri ("resource:/org/gtk/iconbrowser/gtk/icon.list");
g_file_load_contents (file, NULL, &data, &length, NULL, NULL);
add_context (win, "multimedia", "Multimedia", "Icons related to playback of media");
add_icon (win, "media-playlist-repeat", "The icon for the repeat mode of a media player", "multimedia");
add_icon (win, "media-playlist-repeat-song", "The icon for repeating a song in a media player", "multimedia");
add_icon (win, "media-playlist-shuffle", "The icon for the shuffle mode of a media player", "multimedia");
add_icon (win, "media-playlist-consecutive", "The icon for consecutive mode of a media player", "multimedia");
add_icon (win, "media-skip-backward", "The icon for the skip backward action of a media player", "multimedia");
add_icon (win, "media-seek-backward", "The icon for the seek backward action of a media player", "multimedia");
add_icon (win, "media-playback-start", "The icon for the start playback action of a media player", "multimedia");
add_icon (win, "media-seek-forward", "The icon for the seek forward action of a media player", "multimedia");
add_icon (win, "media-skip-forward", "The icon for the skip forward action of a media player", "multimedia");
add_icon (win, "media-playback-stop", "The icon for the stop action of a media player", "multimedia");
add_icon (win, "media-playback-pause", "The icon for the pause action of a media player", "multimedia");
add_icon (win, "media-eject", "The icon for the eject action of a media player or file manager", "multimedia");
add_icon (win, "media-record", "The icon for the record action of a media application", "multimedia");
add_icon (win, "media-view-subtitles", "The icon used to show subtitles in a media player", "multimedia");
kf = g_key_file_new ();
g_key_file_load_from_data (kf, data, length, G_KEY_FILE_NONE, NULL);
add_context (win, "network", "Network", "Icons related to network status");
add_icon (win, "network-transmit-receive", "The icon used data is being both transmitted and received simultaneously, while the computing device is connected to a network", "network");
add_icon (win, "network-transmit", "The icon used when data is being transmitted, while the computing device is connected to a network", "network");
add_icon (win, "network-receive", "The icon used when data is being received, while the computing device is connected to a network", "network");
add_icon (win, "network-idle", "The icon used when no data is being transmitted or received, while the computing device is connected to a network", "network");
add_icon (win, "network-error", "The icon used when an error occurs trying to intialize the network connection of the computing device", "network");
add_icon (win, "network-offline", "The icon used when the computing device is disconnected from the network", "network");
groups = g_key_file_get_groups (kf, &length);
for (i = 0; i < length; i++)
{
const char *context;
const char *name;
const char *description;
char **keys;
gsize len;
int j;
add_context (win, "weather", "Weather", "Icons about weather conditions");
add_icon (win, "weather-clear", "The icon used while the weather for a region is “clear skies”", "weather");
add_icon (win, "weather-clear-night", "The icon used while the weather for a region is “clear skies” during the night", "weather");
add_icon (win, "weather-few-clouds", "The icon used while the weather for a region is “partly cloudy”", "weather");
add_icon (win, "weather-few-clouds-night", "The icon used while the weather for a region is “partly cloudy” during the night", "weather");
add_icon (win, "weather-fog", "The icon used while the weather for a region is “foggy”", "weather");
add_icon (win, "weather-overcast", "The icon used while the weather for a region is “overcast”", "weather");
add_icon (win, "weather-severe-alert", "The icon used while a sever weather alert is in effect for a region", "weather");
add_icon (win, "weather-showers", "The icon used while rain showers are occurring in a region", "weather");
add_icon (win, "weather-showers-scattered", "The icon used while scattered rain showers are occurring in a region", "weather");
add_icon (win, "weather-snow", "The icon used while snow showers are occurring in a region", "weather");
add_icon (win, "weather-storm", "The icon used while storms are occurring in a region", "weather");
context = groups[i];
name = g_key_file_get_string (kf, context, "Name", NULL);
description = g_key_file_get_string (kf, context, "Description", NULL);
add_context (win, context, name, description);
add_context (win, "navigation", "Navigation", "Icons for navigation in the user interface of a program");
add_icon (win, "go-first", "The icon for the go to the first item in a list", "navigation");
add_icon (win, "go-previous", "The icon for the go to the previous item in a list", "navigation");
add_icon (win, "go-next", "The icon for the go to the next item in a list", "navigation");
add_icon (win, "go-last", "The icon for the go to the last item in a list", "navigation");
add_icon (win, "go-bottom", "The icon for the go to bottom of a list", "navigation");
add_icon (win, "go-down", "The icon for the go down in a list", "navigation");
add_icon (win, "go-up", "The icon for the go up in a list", "navigation");
add_icon (win, "go-top", "The icon for the go to the top of a list", "navigation");
add_icon (win, "go-home", "The icon for the go to home location", "navigation");
add_icon (win, "go-jump", "The icon for the jump to action", "navigation");
keys = g_key_file_get_keys (kf, context, &len, NULL);
for (j = 0; j < len; j++)
{
const char *key = keys[j];
const char *value;
add_context (win, "editing", "Editing", "Icons related to editing a document");
add_icon (win, "format-indent-less", "The icon for the decrease indent formatting action", "editing");
add_icon (win, "format-indent-more", "The icon for the increase indent formatting action", "editing");
add_icon (win, "format-justify-center", "The icon for the center justification formatting action", "editing");
add_icon (win, "format-justify-fill", "The icon for the fill justification formatting action", "editing");
add_icon (win, "format-justify-left", "The icon for the left justification formatting action", "editing");
add_icon (win, "format-justify-right", "The icon for the right justification action", "editing");
add_icon (win, "format-text-direction-ltr", "The icon for the left-to-right text formatting action", "editing");
add_icon (win, "format-text-direction-rtl", "The icon for the right-to-left formatting action", "editing");
add_icon (win, "format-text-bold", "The icon for the bold text formatting action", "editing");
add_icon (win, "format-text-italic", "The icon for the italic text formatting action", "editing");
add_icon (win, "format-text-underline", "The icon for the underlined text formatting action", "editing");
add_icon (win, "format-text-strikethrough", "The icon for the strikethrough text formatting action", "editing");
add_icon (win, "edit-clear", "The icon for the clear action", "editing");
add_icon (win, "edit-clear-all", "", "editing");
add_icon (win, "edit-copy", "The icon for the copy action", "editing");
add_icon (win, "edit-cut", "The icon for the cut action", "editing");
add_icon (win, "edit-delete", "The icon for the delete action", "editing");
add_icon (win, "edit-find-replace", "The icon for the find and replace action", "editing");
add_icon (win, "edit-paste", "The icon for the paste action", "editing");
add_icon (win, "edit-redo", "The icon for the redo action", "editing");
add_icon (win, "edit-select-all", "The icon for the select all action", "editing");
add_icon (win, "edit-select", "", "editing");
add_icon (win, "edit-undo", "The icon for the undo action", "editing");
add_icon (win, "document-properties", "The icon for the action to view the properties of a document in an application", "editing");
add_icon (win, "document-new", "The icon used for the action to create a new document", "editing");
add_icon (win, "document-open", "The icon used for the action to open a document", "editing");
add_icon (win, "document-open-recent", "The icon used for the action to open a document that was recently opened", "editing");
add_icon (win, "document-save", "The icon for the save action. Should be an arrow pointing down and toward a hard disk", "editing");
add_icon (win, "document-save-as", "The icon for the save as action", "editing");
add_icon (win, "document-send", "The icon for the send action. Should be an arrow pointing up and away from a hard disk", "editing");
add_icon (win, "document-page-setup", "The icon for the page setup action of a document editor", "editing");
add_icon (win, "changes-allow", "", "other");
add_icon (win, "changes-prevent", "", "other");
add_icon (win, "object-flip-horizontal", "The icon for the action to flip an object horizontally", "editing");
add_icon (win, "object-flip-vertical", "The icon for the action to flip an object vertically", "editing");
add_icon (win, "object-rotate-left", "The icon for the rotate left action performed on an object", "editing");
add_icon (win, "object-rotate-right", "The icon for the rotate rigt action performed on an object", "editing");
add_icon (win, "insert-image", "The icon for the insert image action of an application", "editing");
add_icon (win, "insert-link", "The icon for the insert link action of an application", "editing");
add_icon (win, "insert-object", "The icon for the insert object action of an application", "editing");
add_icon (win, "insert-text", "The icon for the insert text action of an application", "editing");
add_icon (win, "accessories-text-editor", "The icon used for the desktop's text editing accessory program", "editing");
if (strcmp (key, "Name") == 0 || strcmp (key, "Description") == 0)
continue;
add_context (win, "view", "View Controls", "Icons for view controls in a user interface");
add_icon (win, "view-list", "The icon used for “List“ view mode", "view");
add_icon (win, "view-grid", "The icon used for “Grid“ view mode (as opposed to “List“)", "view");
add_icon (win, "view-fullscreen", "The icon used for the “Fullscreen” item in the application's “View” menu", "view");
add_icon (win, "view-restore", "The icon used by an application for leaving the fullscreen view, and returning to a normal windowed view", "view");
add_icon (win, "zoom-fit-best", "The icon used for the “Best Fit” item in the application's “View” menu", "view");
add_icon (win, "zoom-in", "The icon used for the “Zoom in” item in the application's “View” menu", "view");
add_icon (win, "zoom-out", "The icon used for the “Zoom Out” item in the application's “View” menu ", "view");
add_icon (win, "zoom-original", "The icon used for the “Original Size” item in the application's “View” menu", "view");
add_icon (win, "view-continuous", "The icon used for a continuous view mode", "view");
add_icon (win, "view-paged", "The icon used for a paged view mode (as opposed to continuous)", "view");
add_icon (win, "view-dual", "The icon used for a side-by-side view of paginated content", "view");
add_icon (win, "view-wrapped", "The icon used to indicate a wrap-around to the beginning", "view");
value = g_key_file_get_string (kf, context, key, NULL);
add_context (win, "calendar", "Calendar, Tasks and Alarms", "Icons related to calendars, tasks and alarms");
add_icon (win, "task-due", "The icon used when a task is due soon", "calendar");
add_icon (win, "task-past-due", "The icon used when a task that was due, has been left incomplete", "calendar");
add_icon (win, "appointment-soon", "The icon used when an appointment will occur soon", "calendar");
add_icon (win, "appointment-missed", "The icon used when an appointment was missed", "calendar");
add_icon (win, "alarm", "The icon used for alarms when a task or appointment is due", "calendar");
add_icon (win, key, value, context);
}
g_strfreev (keys);
}
g_strfreev (groups);
add_context (win, "communication", "Communication", "Icons related email, phone calls, IM and other forms of communication");
add_icon (win, "mail-unread", "The icon used for an electronic mail that is unread", "communication");
add_icon (win, "mail-read", "The icon used for an electronic mail that is read", "communication");
add_icon (win, "mail-replied", "The icon used for an electronic mail that has been replied to", "communication");
add_icon (win, "mail-attachment", "The icon used for an electronic mail that contains attachments", "communication");
add_icon (win, "mail-mark-important", "The icon for the mark as important action of an electronic mail application", "communication");
add_icon (win, "mail-send", "The icon for the send action of an electronic mail application", "communication");
add_icon (win, "mail-send-receive", "The icon for the send and receive action of an electronic mail application", "communication");
add_icon (win, "call-start", "The icon used for initiating or accepting a call", "communication");
add_icon (win, "call-stop", "The icon used for stopping a current call", "communication");
add_icon (win, "call-missed", "The icon used to show a missed call", "communication");
add_icon (win, "user-available", "The icon used when a user on a chat network is available to initiate a conversation with", "communication");
add_icon (win, "user-offline", "The icon used when a user on a chat network is not available", "communication");
add_icon (win, "user-idle", "The icon used when a user on a chat network has not been an active participant in any chats on the network, for an extended period of time", "communication");
add_icon (win, "user-invisible", "The icon used when a user is on a chat network, but is invisible to others", "communication");
add_icon (win, "user-busy", "The icon used when a user is on a chat network, and has marked himself as busy", "communication");
add_icon (win, "user-away", "The icon used when a user on a chat network is away from their keyboard and the chat program", "communication");
add_icon (win, "user-status-pending", "The icon used when the current user status on a chat network is not known", "communication");
add_context (win, "devices", "Devices and Media", "Icons for devices and media");
add_icon (win, "audio-input-microphone", "The icon used for the microphone audio input device", "devices");
add_icon (win, "camera-web", "The fallback icon for web cameras", "devices");
add_icon (win, "camera-photo", "The icon used for a digital still camera devices", "devices");
add_icon (win, "input-keyboard", "The icon used for the keyboard input device", "devices");
add_icon (win, "printer", "The icon used for a printer device", "devices");
add_icon (win, "video-display", "The icon used for the monitor that video gets displayed to", "devices");
add_icon (win, "computer", "The icon used for the computing device as a whole", "devices");
add_icon (win, "media-optical", "The icon used for physical optical media such as CD and DVD", "devices");
add_icon (win, "phone", "The icon used for phone devices which support connectivity to the PC, such as VoIP, cellular, or possibly landline phones", "devices");
add_icon (win, "input-dialpad", "The icon used for dialpad input devices", "devices");
add_icon (win, "input-touchpad", "The icon used for touchpad input devices", "devices");
add_icon (win, "scanner", "The icon used for a scanner device", "devices");
add_icon (win, "audio-card", "The icon used for the audio rendering device", "devices");
add_icon (win, "input-gaming", "The icon used for the gaming input device", "devices");
add_icon (win, "input-mouse", "The icon used for the mousing input device", "devices");
add_icon (win, "multimedia-player", "The icon used for generic multimedia playing devices", "devices");
add_icon (win, "audio-headphones", "The icon used for headphones", "devices");
add_icon (win, "audio-headset", "The icon used for headsets", "devices");
add_icon (win, "display-projector", "The icon used for projectors", "devices");
add_icon (win, "media-removable", "The icon used for generic removable media", "devices");
add_icon (win, "printer-network", "The icon used for printers which are connected via the network", "devices");
add_icon (win, "audio-speakers", "The icon used for speakers", "devices");
add_icon (win, "camera-video", "The fallback icon for video cameras", "devices");
add_icon (win, "drive-optical", "The icon used for optical media drives such as CD and DVD", "devices");
add_icon (win, "drive-removable-media", "The icon used for removable media drives", "devices");
add_icon (win, "input-tablet", "The icon used for graphics tablet input devices", "devices");
add_icon (win, "network-wireless", "The icon used for wireless network connections", "devices");
add_icon (win, "network-wired", "The icon used for wired network connections", "devices");
add_icon (win, "media-floppy", "The icon used for physical floppy disk media", "devices");
add_icon (win, "media-flash", "The fallback icon used for flash media, such as memory stick and SD", "devices");
add_context (win, "contenttypes", "Content Types", "Icons for different types of data, such as audio or image files");
add_icon (win, "application-certificate", "", "contenttypes");
add_icon (win, "application-rss+xml", "", "contenttypes");
add_icon (win, "application-x-appliance", "", "contenttypes");
add_icon (win, "audio-x-generic", "The icon used for generic audio file types", "contenttypes");
add_icon (win, "folder", "The standard folder icon used to represent directories on local filesystems, mail folders, and other hierarchical groups", "contenttypes");
add_icon (win, "text-x-generic", "The icon used for generic text file types", "contenttypes");
add_icon (win, "video-x-generic", "The icon used for generic video file types", "contenttypes");
add_icon (win, "x-office-calendar", "The icon used for generic calendar file types", "contenttypes");
add_context (win, "emotes", "Emotes", "Icons for emotions that are expressed through text chat applications such as :-) or :-P in IRC or instant messengers");
add_icon (win, "face-angel", "The icon used for the 0:-) emote", "emotes");
add_icon (win, "face-angry", "The icon used for the X-( emote", "emotes");
add_icon (win, "face-cool", "The icon used for the B-) emote", "emotes");
add_icon (win, "face-crying", "The icon used for the :'( emote", "emotes");
add_icon (win, "face-devilish", "The icon used for the >:-) emote", "emotes");
add_icon (win, "face-embarrassed", "The icon used for the :-[ emote", "emotes");
add_icon (win, "face-kiss", "The icon used for the :-* emote", "emotes");
add_icon (win, "face-laugh", "The icon used for the :-)) emote", "emotes");
add_icon (win, "face-monkey", "The icon used for the :-(|) emote", "emotes");
add_icon (win, "face-plain", "The icon used for the :-| emote", "emotes");
add_icon (win, "face-raspberry", "The icon used for the :-P emote", "emotes");
add_icon (win, "face-sad", "The icon used for the :-( emote", "emotes");
add_icon (win, "face-shutmouth", "The 'shut mouth' emote", "emotes");
add_icon (win, "face-sick", "The icon used for the :-& emote", "emotes");
add_icon (win, "face-smile", "The icon used for the :-) emote", "emotes");
add_icon (win, "face-smile-big", "The icon used for the :-D emote", "emotes");
add_icon (win, "face-smirk", "The icon used for the :-! emote", "emotes");
add_icon (win, "face-surprise", "The icon used for the :-0 emote", "emotes");
add_icon (win, "face-tired", "The icon used for the |-) emote", "emotes");
add_icon (win, "face-uncertain", "The icon used for the :-/ emote", "emotes");
add_icon (win, "face-wink", "The icon used for the ;-) emote", "emotes");
add_icon (win, "face-worried", "The icon used for the :-S emote", "emotes");
add_icon (win, "face-yawn", "", "emotes");
add_context (win, "general", "General", "Generally useful icons that don't fit in a particular category");
add_icon (win, "edit-find", "The icon for generic search actions", "general");
add_icon (win, "content-loading", "The icon used to indicate that content is loading", "general");
add_icon (win, "open-menu", "The icon used for a menu button in the header bar", "general");
add_icon (win, "view-more", "The icon used for a “View More“ action", "general");
add_icon (win, "tab-new", "The icon used for a “New Tab“ action", "general");
add_icon (win, "bookmark-new", "The icon used for creating a new bookmark", "general");
add_icon (win, "mark-location", "The icon used to mark a location on a map", "general");
add_icon (win, "find-location", "The icon used for a “Search location“ action", "general");
add_icon (win, "send-to", "The icon used for a “Send to“ action", "general");
add_icon (win, "object-select", "The icon used for generic selection actions", "general");
add_icon (win, "window-close", "The icon used for actions that close a view, such as window or tab close button", "general");
add_icon (win, "view-refresh", "The icon used for the “Refresh” item in the application's “View” menu", "general");
add_icon (win, "process-stop", "The icon used for the “Stop” action in applications with actions that may take a while to process, such as web page loading in a browser", "general");
add_icon (win, "action-unavailable", "The icon used to indicate that an action is currently unavailable, such as “Pause“ when no media is playing", "general");
add_icon (win, "document-print", "The icon for the print action of an application", "general");
add_icon (win, "printer-printing", "The icon used while a print job is successfully being spooled to a printing device", "general");
add_icon (win, "printer-warning", "The icon used when a recoverable problem occurs while attempting to printing", "general");
add_icon (win, "printer-error", "The icon used when an error occurs while attempting to print", "general");
add_icon (win, "dialog-information", "The icon used when a dialog is opened to give information to the user that may be pertinent to the requested action", "general");
add_icon (win, "dialog-question", "The icon used when a dialog is opened to ask a simple question of the user", "general");
add_icon (win, "dialog-warning", "The icon used when a dialog is opened to warn the user of impending issues with the requested action", "general");
add_icon (win, "dialog-password", "The icon used when a dialog requesting the authentication credentials for a user is opened", "general");
add_icon (win, "dialog-error", "The icon used when a dialog is opened to explain an error condition to the user", "general");
add_icon (win, "list-add", "The icon for the add to list action", "general");
add_icon (win, "list-remove", "The icon for the remove from list action", "general");
add_icon (win, "non-starred", "The icon used to indicate that an object is not 'starred'", "general");
add_icon (win, "semi-starred", "The icon used to indicate that an object has is 'half-starred'", "general");
add_icon (win, "starred", "The icon used to indicate that an object is 'starred'", "general");
add_icon (win, "star-new", "The used for the “New Star“ action", "general");
add_icon (win, "security-low", "The icon used to indicate that the security level of a connection is presumed to be insecure, either by using weak encryption, or by using a certificate that the could not be automatically verified, and which the user has not chosent to trust", "general");
add_icon (win, "security-medium", "The icon used to indicate that the security level of a connection is presumed to be secure, using strong encryption, and a certificate that could not be automatically verified, but which the user has chosen to trust", "general");
add_icon (win, "security-high", "The icon used to indicate that the security level of a connection is known to be secure, using strong encryption and a valid certificate", "general");
add_icon (win, "user-trash", "The icon for the user's “Trash” place in the file system", "other");
add_icon (win, "user-trash-full", "The icon for the user's “Trash” in the file system, when there are items in the “Trash” waiting for disposal or recovery", "general");
add_icon (win, "emblem-system", "The icon used as an emblem for directories that contain system libraries, settings, and data", "general");
add_icon (win, "avatar-default", "The generic avatar icon, which is used to represent a user that doesn't have a personalized avatar", "general");
add_icon (win, "emblem-synchronizing", "The icon used as an emblem to indicate that a a synchronizing operation is in process", "general");
add_icon (win, "emblem-shared", "The icon used as an emblem for files and directories that are shared to other users", "general");
add_icon (win, "folder-download", "The icon representing the location in the file system where downloaded files are stored", "general");
add_icon (win, "help-browser", "The icon used for the desktop's help browsing application", "general");
add_context (win, "other", "Other", "Icons which have may be too specialized and not of general interest");
add_icon (win, "view-sort-ascending", "The icon used for the “Sort Ascending” item in the application's “View” menu, or in a button for changing the sort method for a list", "other");
add_icon (win, "view-sort-descending", "The icon used for the “Sort Descending” item in the application's “View” menu, or in a button for changing the sort method for a list", "other");
add_icon (win, "document-revert", "The icon for the action of reverting to a previous version of a document", "other");
add_icon (win, "address-book-new", "The icon used for the action to create a new address book", "other");
add_icon (win, "application-exit", "The icon used for exiting an application. Typically this is seen in the application's menus as File->Quit", "other");
add_icon (win, "appointment-new", "The icon used for the action to create a new appointment in a calendaring application", "other");
add_icon (win, "contact-new", "The icon used for the action to create a new contact in an address book application", "other");
add_icon (win, "document-print-preview", "The icon for the print preview action of an application", "other");
add_icon (win, "folder-new", "The icon for creating a new folder", "other");
add_icon (win, "help-about", "The icon for the About item in the Help menu", "other");
add_icon (win, "help-contents", "The icon for Contents item in the Help menu", "other");
add_icon (win, "help-faq", "The icon for the FAQ item in the Help menu", "other");
add_icon (win, "list-remove-all", "", "other");
add_icon (win, "mail-forward", "The icon for the forward action of an electronic mail application", "other");
add_icon (win, "mail-mark-junk", "The icon for the mark as junk action of an electronic mail application", "other");
add_icon (win, "mail-mark-notjunk", "The icon for the mark as not junk action of an electronic mail application", "other");
add_icon (win, "mail-mark-read", "The icon for the mark as read action of an electronic mail application", "other");
add_icon (win, "mail-mark-unread", "The icon for the mark as unread action of an electronic mail application", "other");
add_icon (win, "mail-message-new", "The icon for the compose new mail action of an electronic mail application", "other");
add_icon (win, "mail-reply-all", "The icon for the reply to all action of an electronic mail application", "other");
add_icon (win, "mail-reply-sender", "The icon for the reply to sender action of an electronic mail application", "other");
add_icon (win, "pan-down", "", "other");
add_icon (win, "pan-end", "", "other");
add_icon (win, "pan-start", "", "other");
add_icon (win, "pan-up", "", "other");
add_icon (win, "system-lock-screen", "The icon used for the “Lock Screen” item in the desktop's panel application", "other");
add_icon (win, "system-log-out", "The icon used for the “Log Out” item in the desktop's panel application", "other");
add_icon (win, "system-run", "The icon used for the “Run Application...” item in the desktop's panel application", "other");
add_icon (win, "system-search", "The icon used for the “Search” item in the desktop's panel application", "other");
add_icon (win, "system-reboot", "The icon used for the “Reboot” item in the desktop's panel application", "other");
add_icon (win, "system-shutdown", "The icon used for the “Shutdown” item in the desktop's panel application", "other");
add_icon (win, "tools-check-spelling", "The icon used for the “Check Spelling” item in the application's “Tools” menu", "other");
add_icon (win, "window-maximize", "", "other");
add_icon (win, "window-minimize", "", "other");
add_icon (win, "window-restore", "", "other");
add_icon (win, "window-new", "The icon used for the “New Window” item in the application's “Windows” menu", "other");
add_icon (win, "accessories-calculator", "The icon used for the desktop's calculator accessory program", "other");
add_icon (win, "accessories-character-map", "The icon used for the desktop's international and extended text character accessory program", "other");
add_icon (win, "accessories-dictionary", "The icon used for the desktop's dictionary accessory program", "other");
add_icon (win, "multimedia-volume-control", "The icon used for the desktop's hardware volume control application", "other");
add_icon (win, "preferences-desktop-accessibility", "The icon used for the desktop's accessibility preferences", "other");
add_icon (win, "preferences-desktop-display", "", "other");
add_icon (win, "preferences-desktop-font", "The icon used for the desktop's font preferences", "other");
add_icon (win, "preferences-desktop-keyboard", "The icon used for the desktop's keyboard preferences", "other");
add_icon (win, "preferences-desktop-keyboard-shortcuts", "", "other");
add_icon (win, "preferences-desktop-locale", "The icon used for the desktop's locale preferences", "other");
add_icon (win, "preferences-desktop-remote-desktop", "", "other");
add_icon (win, "preferences-desktop-multimedia", "The icon used for the desktop's multimedia preferences", "other");
add_icon (win, "preferences-desktop-screensaver", "The icon used for the desktop's screen saving preferences", "other");
add_icon (win, "preferences-desktop-theme", "The icon used for the desktop's theme preferences", "other");
add_icon (win, "preferences-desktop-wallpaper", "The icon used for the desktop's wallpaper preferences", "other");
add_icon (win, "preferences-system-privacy", "", "other");
add_icon (win, "preferences-system-windows", "", "other");
add_icon (win, "system-file-manager", "The icon used for the desktop's file management application", "other");
add_icon (win, "system-software-install", "The icon used for the desktop's software installer application", "other");
add_icon (win, "system-software-update", "The icon used for the desktop's software updating application", "other");
add_icon (win, "system-users", "", "other");
add_icon (win, "user-info", "", "other");
add_icon (win, "utilities-system-monitor", "The icon used for the desktop's system resource monitor application", "other");
add_icon (win, "utilities-terminal", "The icon used for the desktop's terminal emulation application. ", "other");
add_icon (win, "application-x-addon", "", "other");
add_icon (win, "application-x-executable", "The icon used for executable file types", "other");
add_icon (win, "font-x-generic", "The icon used for generic font file types", "other");
add_icon (win, "image-x-generic", "The icon used for generic image file types", "other");
add_icon (win, "package-x-generic", "The icon used for generic package file types", "other");
add_icon (win, "text-html", "The icon used for HTML text file types", "other");
add_icon (win, "text-x-generic-template", "The icon used for generic text templates", "other");
add_icon (win, "text-x-preview", "", "other");
add_icon (win, "text-x-script", "The icon used for script file types, such as shell scripts", "other");
add_icon (win, "x-office-address-book", "The icon used for generic address book file types", "other");
add_icon (win, "x-office-document", "The icon used for generic document and letter file types", "other");
add_icon (win, "x-office-document-template", "", "other");
add_icon (win, "x-office-presentation", "The icon used for generic presentation file types", "other");
add_icon (win, "x-office-presentation-template", "", "other");
add_icon (win, "x-office-spreadsheet", "The icon used for generic spreadsheet file types", "other");
add_icon (win, "x-office-spreadsheet-template", "", "other");
add_icon (win, "x-package-repository", "", "other");
add_icon (win, "applications-accessories", "The icon for the “Accessories” sub-menu of the Programs menu", "other");
add_icon (win, "applications-development", "The icon for the “Programming” sub-menu of the Programs menu", "other");
add_icon (win, "applications-engineering", "The icon for the “Engineering” sub-menu of the Programs menu", "other");
add_icon (win, "applications-games", "The icon for the “Games” sub-menu of the Programs menu", "other");
add_icon (win, "applications-graphics", "The icon for the “Graphics” sub-menu of the Programs menu", "other");
add_icon (win, "applications-internet", "The icon for the “Internet” sub-menu of the Programs menu", "other");
add_icon (win, "applications-multimedia", "The icon for the “Multimedia” sub-menu of the Programs menu", "other");
add_icon (win, "applications-office", "The icon for the “Office” sub-menu of the Programs menu", "other");
add_icon (win, "applications-other", "The icon for the “Other” sub-menu of the Programs menu", "other");
add_icon (win, "applications-science", "The icon for the “Science” sub-menu of the Programs menu", "other");
add_icon (win, "applications-system", "The icon for the “System Tools” sub-menu of the Programs menu", "other");
add_icon (win, "applications-utilities", "The icon for the “Utilities” sub-menu of the Programs menu", "other");
add_icon (win, "preferences-desktop", "The icon for the “Desktop Preferences” category", "other");
add_icon (win, "preferences-desktop-peripherals", "The icon for the “Peripherals” sub-category of the “Desktop Preferences” category", "other");
add_icon (win, "preferences-desktop-personal", "The icon for the “Personal” sub-category of the “Desktop Preferences” category", "other");
add_icon (win, "preferences-other", "The icon for the “Other” preferences category", "other");
add_icon (win, "preferences-system", "The icon for the “System Preferences” category", "other");
add_icon (win, "preferences-system-network", "The icon for the “Network” sub-category of the “System Preferences” category", "other");
add_icon (win, "system-help", "The icon for the “Help” system category", "other");
add_icon (win, "battery", "The icon used for the system battery device", "other");
add_icon (win, "computer-apple-ipad", "", "other");
add_icon (win, "colorimeter-colorhug", "", "other");
add_icon (win, "drive-harddisk", "The icon used for hard disk drives", "other");
add_icon (win, "drive-harddisk-ieee1394", "", "other");
add_icon (win, "drive-harddisk-system", "", "other");
add_icon (win, "drive-multidisk", "", "other");
add_icon (win, "media-optical-bd", "", "other");
add_icon (win, "media-optical-cd-audio", "", "other");
add_icon (win, "media-optical-dvd", "", "other");
add_icon (win, "media-tape", "The icon used for generic physical tape media", "other");
add_icon (win, "media-zip", "", "other");
add_icon (win, "modem", "The icon used for modem devices", "other");
add_icon (win, "multimedia-player-apple-ipod-touch", "", "other");
add_icon (win, "network-vpn", "", "other");
add_icon (win, "pda", "This is the fallback icon for Personal Digial Assistant devices. Primary use of this icon is for PDA devices connected to the PC. Connection medium is not an important aspect of the icon. The metaphor for this fallback icon should be a generic PDA device icon", "other");
add_icon (win, "phone-apple-iphone", "", "other");
add_icon (win, "uninterruptible-power-supply", "", "other");
add_icon (win, "emblem-default", "The icon used as an emblem to specify the default selection of a printer for example", "other");
add_icon (win, "emblem-documents", "The icon used as an emblem for the directory where a user's documents are stored", "other");
add_icon (win, "emblem-downloads", "The icon used as an emblem for the directory where a user's downloads from the internet are stored", "other");
add_icon (win, "emblem-favorite", "The icon used as an emblem for files and directories that the user marks as favorites", "other");
add_icon (win, "emblem-generic", "", "other");
add_icon (win, "emblem-important", "The icon used as an emblem for files and directories that are marked as important by the user", "other");
add_icon (win, "emblem-mail", "The icon used as an emblem to specify the directory where the user's electronic mail is stored", "other");
add_icon (win, "emblem-new", "", "other");
add_icon (win, "emblem-ok", "", "other");
add_icon (win, "emblem-package", "", "other");
add_icon (win, "emblem-photos", "The icon used as an emblem to specify the directory where the user stores photographs", "other");
add_icon (win, "emblem-readonly", "The icon used as an emblem for files and directories which can not be written to by the user", "other");
add_icon (win, "emblem-symbolic-link", "The icon used as an emblem for files and direcotires that are links to other files or directories on the filesystem", "other");
add_icon (win, "emblem-synchronized", "The icon used as an emblem for files or directories that are configured to be synchronized to another device", "other");
add_icon (win, "emblem-unreadable", "The icon used as an emblem for files and directories that are inaccessible. ", "other");
add_icon (win, "emblem-urgent", "", "other");
add_icon (win, "emblem-videos", "", "other");
add_icon (win, "emblem-web", "", "other");
add_icon (win, "folder-documents", "", "other");
add_icon (win, "folder-download", "", "other");
add_icon (win, "folder-music", "", "other");
add_icon (win, "folder-pictures", "", "other");
add_icon (win, "folder-documents", "", "other");
add_icon (win, "folder-publicshare", "", "other");
add_icon (win, "folder-remote", "The icon used for normal directories on a remote filesystem", "other");
add_icon (win, "folder-saved-search", "", "other");
add_icon (win, "folder-templates", "", "other");
add_icon (win, "folder-videos", "", "other");
add_icon (win, "network-server", "The icon used for individual host machines under the “Network Servers” place in the file manager", "other");
add_icon (win, "network-workgroup", "The icon for the “Network Servers” place in the desktop's file manager, and workgroups within the network", "other");
add_icon (win, "start-here", "The icon used by the desktop's main menu for accessing places, applications, and other features", "other");
add_icon (win, "user-bookmarks", "The icon for the user's special “Bookmarks” place", "other");
add_icon (win, "user-desktop", "The icon for the special “Desktop” directory of the user", "other");
add_icon (win, "user-home", "The icon for the special “Home” directory of the user", "other");
add_icon (win, "airplane-mode", "", "other");
add_icon (win, "battery-caution-charging", "", "other");
add_icon (win, "battery-caution", "The icon used when the battery is below 40%", "other");
add_icon (win, "battery-empty-charging", "", "other");
add_icon (win, "battery-empty", "", "other");
add_icon (win, "battery-full-charged", "", "other");
add_icon (win, "battery-full-charging", "", "other");
add_icon (win, "battery-full", "", "other");
add_icon (win, "battery-good-charging", "", "other");
add_icon (win, "battery-good", "", "other");
add_icon (win, "battery-low-charging", "", "other");
add_icon (win, "battery-low", "The icon used when the battery is below 20%", "other");
add_icon (win, "battery-missing", "", "other");
add_icon (win, "bluetooth-active", "", "other");
add_icon (win, "bluetooth-disabled", "", "other");
add_icon (win, "channel-insecure", "", "other");
add_icon (win, "channel-secure", "", "other");
add_icon (win, "computer-fail", "", "other");
add_icon (win, "display-brightness", "", "other");
add_icon (win, "keyboard-brightness", "", "other");
add_icon (win, "folder-drag-accept", "The icon used for a folder while an object is being dragged onto it, that is of a type that the directory can contain", "other");
add_icon (win, "folder-open", "The icon used for folders, while their contents are being displayed within the same window. This icon would normally be shown in a tree or list view, next to the main view of a folder's contents", "other");
add_icon (win, "folder-visiting", "The icon used for folders, while their contents are being displayed in another window. This icon would typically be used when using multiple windows to navigate the hierarchy, such as in Nautilus's spatial mode", "other");
add_icon (win, "image-loading", "The icon used when another image is being loaded, such as thumnails for larger images in the file manager", "other");
add_icon (win, "image-missing", "The icon used when another image could not be loaded", "other");
add_icon (win, "mail-signed", "The icon used for an electronic mail that contains a signature", "other");
add_icon (win, "mail-signed-verified", "The icon used for an electronic mail that contains a signature which has also been verified by the security system", "other");
add_icon (win, "network-cellular-3g", "", "other");
add_icon (win, "network-cellular-4g", "", "other");
add_icon (win, "network-cellular-edge", "", "other");
add_icon (win, "network-cellular-gprs", "", "other");
add_icon (win, "network-cellular-umts", "", "other");
add_icon (win, "network-cellular-acquiring", "", "other");
add_icon (win, "network-cellular-connected", "", "other");
add_icon (win, "network-cellular-no-route", "", "other");
add_icon (win, "network-cellular-offline", "", "other");
add_icon (win, "network-cellular-signal-excellent", "", "other");
add_icon (win, "network-cellular-signal-good", "", "other");
add_icon (win, "network-cellular-signal-ok", "", "other");
add_icon (win, "network-cellular-signal-weak", "", "other");
add_icon (win, "network-cellular-signal-none", "", "other");
add_icon (win, "network-vpn-acquiring", "", "other");
add_icon (win, "network-vpn", "", "other");
add_icon (win, "network-wired-acquiring", "", "other");
add_icon (win, "network-wired-disconnected", "", "other");
add_icon (win, "network-wired-no-route", "", "other");
add_icon (win, "network-wired-offline", "", "other");
add_icon (win, "network-wireless-acquiring", "", "other");
add_icon (win, "network-wireless-connected", "", "other");
add_icon (win, "network-wireless-encrypted", "", "other");
add_icon (win, "network-wireless-hotspot", "", "other");
add_icon (win, "network-wireless-no-route", "", "other");
add_icon (win, "network-wireless-offline", "", "other");
add_icon (win, "network-wireless-signal-excellent", "", "other");
add_icon (win, "network-wireless-signal-good", "", "other");
add_icon (win, "network-wireless-signal-ok", "", "other");
add_icon (win, "network-wireless-signal-weak", "", "other");
add_icon (win, "network-wireless-signal-none", "", "other");
add_icon (win, "rotation-allowed", "", "other");
add_icon (win, "rotation-locked", "", "other");
add_icon (win, "software-update-available", "The icon used when an update is available for software installed on the computing device, through the system software update program", "other");
add_icon (win, "software-update-urgent", "The icon used when an urgent update is available through the system software update program", "other");
add_icon (win, "sync-error", "The icon used when an error occurs while attempting to synchronize data from the computing device, to another device", "other");
add_icon (win, "sync-synchronizing", "The icon used while data is successfully synchronizing to another device", "other");
add_icon (win, "touchpad-disabled", "", "other");
add_icon (win, "trophy-bronze", "", "other");
add_icon (win, "trophy-silver", "", "other");
add_icon (win, "trophy-gold", "", "other");
}
static gboolean
@@ -281,16 +694,6 @@ key_press_event_cb (GtkWidget *widget,
return gtk_search_bar_handle_event (GTK_SEARCH_BAR (win->searchbar), event);
}
static void
copy_to_clipboard (GtkButton *button,
IconBrowserWindow *win)
{
GtkClipboard *clipboard;
clipboard = gtk_clipboard_get_default (gdk_display_get_default ());
gtk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)), -1);
}
static gboolean
icon_visible_func (GtkTreeModel *model,
GtkTreeIter *iter,
@@ -345,7 +748,7 @@ symbolic_toggled (GtkToggleButton *toggle, IconBrowserWindow *win)
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->cell, "icon-name", column, NULL);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (win->list), win->text_cell, "text", column, NULL);
gtk_tree_model_filter_refilter (win->filter_model);
gtk_widget_queue_draw (win->list);
}
@@ -383,9 +786,12 @@ get_image_data (GtkWidget *widget,
static void
setup_image_dnd (GtkWidget *image)
{
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (image);
g_signal_connect (image, "drag-data-get", G_CALLBACK (get_image_data), NULL);
GtkWidget *parent;
parent = gtk_widget_get_parent (image);
gtk_drag_source_set (parent, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
gtk_drag_source_add_image_targets (parent);
g_signal_connect (parent, "drag-data-get", G_CALLBACK (get_image_data), NULL);
}
static void
@@ -415,7 +821,7 @@ icon_browser_window_init (IconBrowserWindow *win)
setup_image_dnd (win->image4);
setup_image_dnd (win->image5);
win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, context_free);
win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
gtk_tree_model_filter_set_visible_func (win->filter_model, icon_visible_func, win, NULL);
gtk_window_set_transient_for (GTK_WINDOW (win->details), GTK_WINDOW (win));
@@ -460,7 +866,6 @@ icon_browser_window_class_init (IconBrowserWindowClass *class)
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), selected_context_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), key_press_event_cb);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
}
IconBrowserWindow *
+41 -31
View File
@@ -110,7 +110,7 @@
<object class="GtkCellRendererPixbuf" id="cell">
<property name="xpad">10</property>
<property name="ypad">10</property>
<property name="stock-size">6</property>
<property name="stock-size">5</property>
</object>
</child>
<child>
@@ -151,10 +151,15 @@
<property name="row-spacing">18</property>
<property name="column-spacing">18</property>
<child>
<object class="GtkImage" id="image1">
<object class="GtkEventBox">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
@@ -162,10 +167,15 @@
</packing>
</child>
<child>
<object class="GtkImage" id="image2">
<object class="GtkEventBox">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
<child>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">1</property>
@@ -173,10 +183,15 @@
</packing>
</child>
<child>
<object class="GtkImage" id="image3">
<object class="GtkEventBox">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">2</property>
@@ -184,10 +199,15 @@
</packing>
</child>
<child>
<object class="GtkImage" id="image4">
<object class="GtkEventBox">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
<child>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">3</property>
@@ -195,10 +215,15 @@
</packing>
</child>
<child>
<object class="GtkImage" id="image5">
<object class="GtkEventBox">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
<child>
<object class="GtkImage" id="image5">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="valign">end</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">4</property>
@@ -295,21 +320,6 @@
<property name="width">5</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="label" translatable="yes">Copy to Clipboard</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin">20</property>
<signal name="clicked" handler="copy_to_clipboard"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">4</property>
<property name="width">5</property>
</packing>
</child>
</object>
</child>
</object>
+4 -4
View File
@@ -472,7 +472,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<property name="invisible_char">•</property>
<property name="placeholder-text" translatable="yes">Click icon to change mode</property>
<property name="secondary_icon_name">view-refresh-symbolic</property>
<property name="secondary_icon_tooltip_text">Change mode</property>
<signal name="icon-release" handler="on_entry_icon_release" swapped="no"/>
</object>
<packing>
@@ -585,6 +584,7 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
<child>
<object class="GtkSpinButton" id="spinbutton1">
<property name="can_focus">1</property>
<property name="invisible_char">•</property>
<property name="width-chars">2</property>
<property name="max-width-chars">2</property>
<property name="adjustment">adjustment2</property>
@@ -594,8 +594,9 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spinbutton2">
<object class="GtkSpinButton" id="spinbutton2">
<property name="can_focus">1</property>
<property name="invisible_char">•</property>
<property name="sensitive">0</property>
<property name="width-chars">2</property>
<property name="max-width-chars">2</property>
@@ -2287,7 +2288,7 @@ microphone-sensitivity-medium-symbolic</property>
</child>
<child>
<object class="GtkStatusbar" id="statusbar">
<property name="visible">1</property>
<property name="visible">0</property>
</object>
</child>
</object>
@@ -2494,7 +2495,6 @@ microphone-sensitivity-medium-symbolic</property>
<property name="height-request">300</property>
<property name="halign">start</property>
<property name="shadow-type">in</property>
<property name="hexpand">0</property>
<child>
<object class="GtkTreeView" id="charletree">
<property name="enable-grid-lines">vertical</property>
+3
View File
@@ -4,6 +4,9 @@
<SECTION>
<TITLE>General</TITLE>
<FILE>general</FILE>
gdk_init
gdk_init_check
gdk_parse_args
gdk_get_display_arg_name
gdk_notify_startup_complete
gdk_notify_startup_complete_with_id
+6 -6
View File
@@ -329,7 +329,7 @@ label:focus {
</example>
<example>
<title>Theme indeterminate checkbuttons</title>
<title>Theme inconsistent checkbuttons</title>
<programlisting><![CDATA[
checkbutton:indeterminate {
background-color: #20395a;
@@ -421,13 +421,13 @@ checkbutton:indeterminate {
<entry>E:active, E:hover, E:focus</entry>
<entry>any E node which is part of a widget with the corresponding state</entry>
<entry><ulink url="https://www.w3.org/TR/css3-selectors/#useraction-pseudos">CSS</ulink></entry>
<entry>Correspond to GTK_STATE_FLAG_ACTIVE, GTK_STATE_FLAG_PRELIGHT and GTK_STATE_FLAGS_FOCUSED respectively</entry>
<entry>Corresponds to GTK_STATE_FLAG_ACTIVE, GTK_STATE_FLAG_PRELIGHT and GTK_STATE_FLAGS_FOCUSED; GTK+ also allows E:prelight and E:focused</entry>
</row>
<row>
<entry>E:disabled</entry>
<entry>any E node which is part of a widget which is disabled</entry>
<entry>any E node which is part of a widget with is disabled</entry>
<entry><ulink url="https://www.w3.org/TR/css3-selectors/#UIstates">CSS</ulink></entry>
<entry>Corresponds to GTK_STATE_FLAG_INSENSITIVE</entry>
<entry>Corresponds to GTK_STATE_FLAG_INSENSITIVE; GTK+ also allows E:insensitive</entry>
</row>
<row>
<entry>E:checked</entry>
@@ -437,10 +437,10 @@ checkbutton:indeterminate {
</row>
<row>
<entry>E:indeterminate</entry>
<entry>any E node which is part of a widget (e.g. radio- or checkbuttons) which is in an indeterminate state</entry>
<entry>any E node which is part of a widget (e.g. radio- or checkbuttons) which is in an inconsistent state</entry>
<entry><ulink url="https://www.w3.org/TR/css3-selectors/#indeterminate">CSS3</ulink>,
<ulink url="https://drafts.csswg.org/selectors/#indeterminate">CSS4</ulink></entry>
<entry>Corresponds to GTK_STATE_FLAG_INCONSISTENT</entry>
<entry>Corresponds to GTK_STATE_FLAG_INCONSISTENT; GTK+ also allows E:inconsistent</entry>
</row>
<row>
<entry>E:backdrop, E:selected</entry>
+75
View File
@@ -342,6 +342,81 @@ my_widget_init (MyWidget *widget)
</refsect2>
</refsect1>
<refsect1 id="app-paintable-widgets">
<title>App-paintable widgets</title>
<para>
Generally, applications use the pre-defined widgets in GTK+ and
they do not draw extra things on top of them (the exception
being <classname>GtkDrawingArea</classname>). However,
applications may sometimes find it convenient to draw directly
on certain widgets like toplevel windows or event boxes. When
this is the case, GTK+ needs to be told not to overwrite your
drawing afterwards, when the window gets to drawing its default
contents.
</para>
<para>
<classname>GtkWindow</classname> and
<classname>GtkEventBox</classname> are the two widgets that allow
turning off drawing of default contents by calling
<function>gtk_widget_set_app_paintable()</function>. If you call
this function, they will not draw their contents and let you do
it instead.
</para>
<para>
Since the #GtkWidget::draw signal runs user-connected handlers
<emphasis>before</emphasis> the widget's default handler, what
usually happens is this:
</para>
<orderedlist>
<listitem>
<para>
Your own draw handler gets run. It paints something
on the window or the event box.
</para>
</listitem>
<listitem>
<para>
The widget's default draw handler gets run. If
<function>gtk_widget_set_app_paintable()</function> has not
been called to turn off widget drawing (this
is the default), <emphasis>your drawing will be
overwritten</emphasis>. An app paintable widget will not
draw its default contents however and preserve your drawing
instead.
</para>
</listitem>
<listitem>
<para>
The draw handler for the parent class gets run.
Since both <classname>GtkWindow</classname> and
<classname>GtkEventBox</classname> are descendants of
<classname>GtkContainer</classname>, their no-window
children will be asked to draw themselves recursively, as
described in <xref linkend="hierarchical-drawing"/>.
</para>
</listitem>
</orderedlist>
<formalpara>
<title>Summary of app-paintable widgets</title>
<para>
Call <function>gtk_widget_set_app_paintable()</function> if you
intend to draw your own content directly on a
<classname>GtkWindow</classname> and
<classname>GtkEventBox</classname>. You seldom need to draw
on top of other widgets, and
<classname>GtkDrawingArea</classname> ignores this flag, as it
<emphasis>is</emphasis> intended to be drawn on.
</para>
</formalpara>
</refsect1>
</refentry>
<!--
+1
View File
@@ -253,6 +253,7 @@
<xi:include href="xml/gtkcalendar.xml" />
<xi:include href="xml/gtkdrawingarea.xml" />
<xi:include href="xml/gtkglarea.xml" />
<xi:include href="xml/gtkeventbox.xml" />
<xi:include href="xml/gtkimcontextsimple.xml" />
<xi:include href="xml/gtkimmulticontext.xml" />
<xi:include href="xml/gtksizegroup.xml" />
+44 -18
View File
@@ -37,8 +37,6 @@ gtk_about_dialog_get_logo
gtk_about_dialog_set_logo
gtk_about_dialog_get_logo_icon_name
gtk_about_dialog_set_logo_icon_name
gtk_about_dialog_get_system_information
gtk_about_dialog_set_system_information
gtk_about_dialog_add_credit_section
gtk_show_about_dialog
<SUBSECTION Standard>
@@ -145,8 +143,6 @@ gtk_accel_label_get_accel_width
gtk_accel_label_set_accel
gtk_accel_label_get_accel
gtk_accel_label_refetch
gtk_accel_label_set_label
gtk_accel_label_get_label
<SUBSECTION Standard>
GTK_ACCEL_LABEL
GTK_IS_ACCEL_LABEL
@@ -356,8 +352,6 @@ gtk_center_box_set_end_widget
gtk_center_box_get_start_widget
gtk_center_box_get_center_widget
gtk_center_box_get_end_widget
gtk_center_box_set_baseline_position
gtk_center_box_get_baseline_position
<PRIVATE>
GTK_TYPE_CENTER_BOX
GTK_CENTER_BOX
@@ -365,8 +359,6 @@ GTK_CENTER_BOX_CLASS
GTK_IS_CENTER_BOX
GTK_IS_CENTER_BOX_CLASS
GTK_CENTER_BOX_GET_CLASS
<SUBSECTION Private>
gtk_center_box_get_type
</SECTION>
<SECTION>
@@ -799,6 +791,7 @@ gtk_dialog_set_default_response
gtk_dialog_set_response_sensitive
gtk_dialog_get_response_for_widget
gtk_dialog_get_widget_for_response
gtk_dialog_get_action_area
gtk_dialog_get_content_area
gtk_dialog_get_header_bar
@@ -1030,6 +1023,28 @@ GtkEntryCompletionPrivate
gtk_entry_completion_get_type
</SECTION>
<SECTION>
<FILE>gtkeventbox</FILE>
<TITLE>GtkEventBox</TITLE>
GtkEventBox
GtkEventBoxClass
gtk_event_box_new
gtk_event_box_set_above_child
gtk_event_box_get_above_child
gtk_event_box_set_visible_window
gtk_event_box_get_visible_window
<SUBSECTION Standard>
GTK_EVENT_BOX
GTK_IS_EVENT_BOX
GTK_TYPE_EVENT_BOX
GTK_EVENT_BOX_CLASS
GTK_IS_EVENT_BOX_CLASS
GTK_EVENT_BOX_GET_CLASS
<SUBSECTION Private>
GtkEventBoxPrivate
gtk_event_box_get_type
</SECTION>
<SECTION>
<FILE>gtkexpander</FILE>
<TITLE>GtkExpander</TITLE>
@@ -1417,6 +1432,7 @@ gtk_icon_view_set_pixbuf_column
gtk_icon_view_get_pixbuf_column
gtk_icon_view_get_path_at_pos
gtk_icon_view_get_item_at_pos
gtk_icon_view_convert_widget_to_bin_window_coords
gtk_icon_view_set_cursor
gtk_icon_view_get_cursor
gtk_icon_view_selected_foreach
@@ -1532,6 +1548,7 @@ GtkImageGIconData
GtkIMContext
GtkIMContextClass
GtkIMContextInfo
gtk_im_context_set_client_window
gtk_im_context_get_preedit_string
gtk_im_context_filter_keypress
gtk_im_context_focus_in
@@ -1686,6 +1703,7 @@ gtk_layout_put
gtk_layout_move
gtk_layout_set_size
gtk_layout_get_size
gtk_layout_get_bin_window
<SUBSECTION Standard>
GTK_LAYOUT
GTK_IS_LAYOUT
@@ -2041,6 +2059,7 @@ gtk_paned_get_child1
gtk_paned_get_child2
gtk_paned_set_position
gtk_paned_get_position
gtk_paned_get_handle_window
gtk_paned_set_wide_handle
gtk_paned_get_wide_handle
<SUBSECTION Standard>
@@ -2501,8 +2520,6 @@ gtk_scrollable_get_type
<TITLE>GtkScrollbar</TITLE>
GtkScrollbar
gtk_scrollbar_new
gtk_scrollbar_get_adjustment
gtk_scrollbar_set_adjustment
<SUBSECTION Standard>
GTK_SCROLLBAR
GTK_IS_SCROLLBAR
@@ -2720,12 +2737,6 @@ gtk_spin_button_get_snap_to_ticks
gtk_spin_button_get_update_policy
gtk_spin_button_get_value
gtk_spin_button_get_wrap
gtk_spin_button_set_text
gtk_spin_button_get_text
gtk_spin_button_set_max_width_chars
gtk_spin_button_get_max_width_chars
gtk_spin_button_set_width_chars
gtk_spin_button_get_width_chars
GTK_INPUT_ERROR
<SUBSECTION Standard>
GTK_SPIN_BUTTON
@@ -4452,6 +4463,7 @@ gtk_volume_button_get_type
<TITLE>GtkSnapshot</TITLE>
GtkSnapshot
gtk_snapshot_push
gtk_snapshot_push_node
gtk_snapshot_push_transform
gtk_snapshot_push_opacity
gtk_snapshot_push_color_matrix
@@ -4461,6 +4473,8 @@ gtk_snapshot_push_rounded_clip
gtk_snapshot_push_cross_fade
gtk_snapshot_push_blend
gtk_snapshot_pop
gtk_snapshot_set_transform
gtk_snapshot_transform
gtk_snapshot_offset
gtk_snapshot_get_offset
gtk_snapshot_append_node
@@ -4507,6 +4521,7 @@ GtkTickCallback
gtk_widget_add_tick_callback
gtk_widget_remove_tick_callback
gtk_widget_size_allocate
gtk_widget_size_allocate_with_baseline
gtk_widget_add_accelerator
gtk_widget_remove_accelerator
gtk_widget_set_accel_path
@@ -4549,7 +4564,11 @@ gtk_widget_queue_draw_area
gtk_widget_queue_draw_region
gtk_widget_set_redraw_on_allocate
gtk_widget_mnemonic_activate
gtk_widget_class_install_style_property
gtk_widget_class_find_style_property
gtk_widget_send_focus_change
gtk_widget_style_get
gtk_widget_style_get_valist
gtk_widget_class_set_accessible_type
gtk_widget_class_set_accessible_role
gtk_widget_get_accessible
@@ -4584,12 +4603,15 @@ gtk_widget_trigger_tooltip_query
gtk_widget_get_window
gtk_widget_register_window
gtk_widget_unregister_window
gtk_cairo_transform_to_window
gtk_widget_get_allocated_width
gtk_widget_get_allocated_height
gtk_widget_get_allocation
gtk_widget_set_allocation
gtk_widget_get_allocated_baseline
gtk_widget_get_allocated_size
gtk_widget_get_clip
gtk_widget_set_clip
gtk_widget_get_can_default
gtk_widget_set_can_default
gtk_widget_get_can_focus
@@ -4869,8 +4891,10 @@ gtk_window_group_get_type
gtk_disable_setlocale
gtk_get_default_language
gtk_get_locale_direction
gtk_parse_args
gtk_init
gtk_init_check
gtk_get_option_group
gtk_events_pending
gtk_main
gtk_main_level
@@ -4902,8 +4926,6 @@ gtk_get_current_event_time
gtk_get_current_event_state
gtk_get_current_event_device
gtk_get_event_widget
gtk_get_event_target
gtk_get_event_target_with_type
gtk_propagate_event
<SUBSECTION Private>
@@ -4986,6 +5008,7 @@ GTK_STYLE_PROVIDER_PRIORITY_THEME
GTK_STYLE_PROVIDER_PRIORITY_SETTINGS
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
GTK_STYLE_PROVIDER_PRIORITY_USER
gtk_style_provider_get_style_property
<SUBSECTION Standard>
GTK_TYPE_STYLE_PROVIDER
GTK_STYLE_PROVIDER
@@ -5106,6 +5129,9 @@ gtk_style_context_get_property
gtk_style_context_get_screen
gtk_style_context_get_frame_clock
gtk_style_context_get_state
gtk_style_context_get_style
gtk_style_context_get_style_property
gtk_style_context_get_style_valist
gtk_style_context_get_valist
gtk_style_context_get_section
gtk_style_context_get_color
+1
View File
@@ -55,6 +55,7 @@ gtk_editable_get_type
gtk_entry_buffer_get_type
gtk_entry_completion_get_type
gtk_entry_get_type
gtk_event_box_get_type
gtk_event_controller_get_type
gtk_expander_get_type
gtk_file_chooser_button_get_type
+8
View File
@@ -191,6 +191,14 @@
for the widgets #GdkWindow, and all child #GdkWindows.
</para>
<para>
If a widget is windowless (gtk_widget_get_has_window() returns %FALSE) and
an application wants to receive custom events on it, it must be placed
inside a #GtkEventBox to receive the events, and an appropriate event mask
must be set on the box. When implementing a widget, use a %GDK_INPUT_ONLY
#GdkWindow to receive the events instead.
</para>
<para>
Filtering events against event masks happens inside #GdkWindow, which
exposes event masks to the windowing system to reduce the number of events
+5
View File
@@ -656,6 +656,11 @@ How do I change the color of a widget?
See gtk_widget_override_color() and gtk_widget_override_background_color().
You can also change the appearance of a widget by installing a
custom style provider, see gtk_style_context_add_provider().
</para>
<para>To change the background color for widgets such as #GtkLabel that
have no background, place them in a #GtkEventBox and set the background
of the event box.
</para></answer>
</qandaentry>
-15
View File
@@ -514,21 +514,6 @@ nevertheless.
</para>
</formalpara>
<formalpara>
<title><envar>GTK_CSD</envar></title>
<para>
The default value of this environment variable is 1. If changed to 0, this
disables the default use of client-side decorations on GTK+ windows, thus
making the window manager responsible for drawing the decorations of
windows that do not have a custom titlebar widget.
</para>
<para>
CSD is always used for windows with a custom titlebar widget set, as the WM
should not draw another titlebar or other decorations around the custom one.
</para>
</formalpara>
<formalpara>
<title><envar>XDG_DATA_HOME</envar>, <envar>XDG_DATA_DIRS</envar></title>
+2 -6
View File
@@ -926,12 +926,8 @@ create_notebook (void)
gtk_notebook_append_page (GTK_NOTEBOOK (widget),
gtk_label_new ("Notebook"),
NULL);
gtk_notebook_append_page (GTK_NOTEBOOK (widget),
gtk_label_new ("Notebook"),
NULL);
gtk_notebook_append_page (GTK_NOTEBOOK (widget),
gtk_label_new ("Notebook"),
NULL);
gtk_notebook_append_page (GTK_NOTEBOOK (widget), gtk_event_box_new (), NULL);
gtk_notebook_append_page (GTK_NOTEBOOK (widget), gtk_event_box_new (), NULL);
return new_widget_info ("notebook", widget, MEDIUM);
}
-1
View File
@@ -426,7 +426,6 @@ gdkmarshalers.c: gdkmarshalers.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
--prefix=_gdk_marshal \
--body \
--prototypes \
$(srcdir)/gdkmarshalers.list > gdkmarshalers-c.tmp \
&& mv gdkmarshalers-c.tmp gdkmarshalers.c \
|| ( rm -f gdkmarshalers-c.tmp && exit 1 )
+3 -1
View File
@@ -2053,7 +2053,9 @@ gdk_error_trap_pop_internal (gboolean need_code)
result = 0;
for (l = trap->displays; l != NULL; l = l->next)
{
gint code = class->pop_error_trap (l->data, !need_code);
gint code = 0;
code = class->pop_error_trap (l->data, !need_code);
/* we use the error on the last display listed, why not. */
if (code != 0)
-7
View File
@@ -156,13 +156,6 @@ struct _GdkEventPrivate
typedef struct _GdkWindowPaint GdkWindowPaint;
typedef enum
{
GDK_INPUT_OUTPUT,
GDK_INPUT_ONLY
} GdkWindowWindowClass;
struct _GdkWindowAttr
{
gint event_mask;
+3 -3
View File
@@ -97,7 +97,7 @@ gdk_rgba_free (GdkRGBA *rgba)
* Checks if an @rgba value is transparent. That is, drawing with the value
* would not produce any change.
*
* Returns: %TRUE if the @rgba is clear
* Returns: %TRUE if the @rgab is clear
*
* Since: 3.90
*/
@@ -114,7 +114,7 @@ gdk_rgba_is_clear (const GdkRGBA *rgba)
* Checks if an @rgba value is opaque. That is, drawing with the value
* will not retain any results from previous contents.
*
* Returns: %TRUE if the @rgba is opaque
* Returns: %TRUE if the @rgab is opaque
*
* Since: 3.90
*/
@@ -184,7 +184,7 @@ parse_rgb_value (const gchar *str,
*
* Where “r”, “g”, “b” and “a” are respectively the red, green, blue and
* alpha color values. In the last two cases, r g and b are either integers
* in the range 0 to 255 or percentage values in the range 0% to 100%, and
* in the range 0 to 255 or precentage values in the range 0% to 100%, and
* a is a floating point value in the range 0 to 1.
*
* Returns: %TRUE if the parsing succeeded
+1 -1
View File
@@ -670,7 +670,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
return FALSE;
}
static VkBool32 VKAPI_CALL
static VkBool32
gdk_vulkan_debug_report (VkDebugReportFlagsEXT flags,
VkDebugReportObjectTypeEXT objectType,
uint64_t object,
+3 -13
View File
@@ -3585,9 +3585,9 @@ gdk_window_show_internal (GdkWindow *window, gboolean raise)
if (gdk_window_has_impl (window))
{
if (!was_mapped)
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_WITHDRAWN,
0);
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_WITHDRAWN,
GDK_WINDOW_STATE_FOCUSED);
}
else
{
@@ -4588,18 +4588,8 @@ gdk_window_set_cursor (GdkWindow *window,
for (s = seats; s; s = s->next)
{
GList *devices, *d;
device = gdk_seat_get_pointer (s->data);
gdk_window_set_cursor_internal (window, device, window->cursor);
devices = gdk_seat_get_slaves (s->data, GDK_SEAT_CAPABILITY_TABLET_STYLUS);
for (d = devices; d; d = d->next)
{
device = gdk_device_get_associated_device (d->data);
gdk_window_set_cursor_internal (window, device, window->cursor);
}
g_list_free (devices);
}
g_list_free (seats);
+18
View File
@@ -38,6 +38,24 @@
G_BEGIN_DECLS
typedef struct _GdkGeometry GdkGeometry;
typedef struct _GdkWindowRedirect GdkWindowRedirect;
/**
* GdkWindowWindowClass:
* @GDK_INPUT_OUTPUT: window for graphics and events
* @GDK_INPUT_ONLY: window for events only
*
* @GDK_INPUT_OUTPUT windows are the standard kind of window you might expect.
* Such windows receive events and are also displayed on screen.
* @GDK_INPUT_ONLY windows are invisible; they are usually placed above other
* windows in order to trap or filter the events. You cant draw on
* @GDK_INPUT_ONLY windows.
*/
typedef enum
{
GDK_INPUT_OUTPUT, /*< nick=input-output >*/
GDK_INPUT_ONLY /*< nick=input-only >*/
} GdkWindowWindowClass;
/**
* GdkWindowType:
-2
View File
@@ -31,8 +31,6 @@ BUILT_SOURCES = \
gtk-primary-selection-protocol.c \
tablet-unstable-v2-client-protocol.h \
tablet-unstable-v2-protocol.c \
keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h \
keyboard-shortcuts-inhibit-unstable-v1-protocol.c \
gtk-shell-client-protocol.h \
gtk-shell-protocol.c
+13 -112
View File
@@ -757,8 +757,6 @@ gdk_wayland_device_grab (GdkDevice *device,
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
{
/* Device is a keyboard */
gdk_wayland_window_inhibit_shortcuts (window,
gdk_device_get_seat (device));
return GDK_GRAB_SUCCESS;
}
else
@@ -815,9 +813,6 @@ gdk_wayland_device_ungrab (GdkDevice *device,
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
{
/* Device is a keyboard */
if (prev_focus)
gdk_wayland_window_restore_shortcuts (prev_focus,
gdk_device_get_seat (device));
}
else
{
@@ -1305,26 +1300,23 @@ static GdkDevice * get_scroll_device (GdkWaylandSeat *seat,
enum wl_pointer_axis_source source);
static GdkEvent *
create_scroll_event (GdkWaylandSeat *seat,
GdkWaylandPointerData *pointer_info,
GdkDevice *device,
GdkDevice *source_device,
gboolean emulated)
create_scroll_event (GdkWaylandSeat *seat,
gboolean emulated)
{
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (seat->display);
GdkEvent *event;
event = gdk_event_new (GDK_SCROLL);
event->scroll.window = g_object_ref (pointer_info->focus);
gdk_event_set_device (event, device);
gdk_event_set_source_device (event, source_device);
event->scroll.time = pointer_info->time;
event->scroll.state = device_get_modifiers (device);
event->scroll.window = g_object_ref (seat->pointer_info.focus);
gdk_event_set_device (event, seat->master_pointer);
gdk_event_set_source_device (event, get_scroll_device (seat, seat->pointer_info.frame.source));
event->scroll.time = seat->pointer_info.time;
event->scroll.state = device_get_modifiers (seat->master_pointer);
gdk_event_set_screen (event, display->screen);
gdk_event_set_pointer_emulated (event, emulated);
get_coordinates (device,
get_coordinates (seat->master_pointer,
&event->scroll.x,
&event->scroll.y,
&event->scroll.x_root,
@@ -1338,11 +1330,8 @@ flush_discrete_scroll_event (GdkWaylandSeat *seat,
GdkScrollDirection direction)
{
GdkEvent *event;
GdkDevice *source;
source = get_scroll_device (seat, seat->pointer_info.frame.source);
event = create_scroll_event (seat, &seat->pointer_info,
seat->master_pointer, source, TRUE);
event = create_scroll_event (seat, TRUE);
event->scroll.direction = direction;
_gdk_wayland_display_deliver_event (seat->display, event);
@@ -1355,11 +1344,8 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat,
gboolean is_stop)
{
GdkEvent *event;
GdkDevice *source;
source = get_scroll_device (seat, seat->pointer_info.frame.source);
event = create_scroll_event (seat, &seat->pointer_info,
seat->master_pointer, source, FALSE);
event = create_scroll_event (seat, FALSE);
event->scroll.direction = GDK_SCROLL_SMOOTH;
event->scroll.delta_x = delta_x;
event->scroll.delta_y = delta_y;
@@ -2881,10 +2867,6 @@ tablet_handle_done (void *data,
GDK_WAYLAND_DEVICE_MANAGER (seat->device_manager);
GdkDevice *master, *stylus_device, *eraser_device;
gchar *master_name, *eraser_name;
gchar *vid, *pid;
vid = g_strdup_printf ("%.4x", tablet->vid);
pid = g_strdup_printf ("%.4x", tablet->pid);
master_name = g_strdup_printf ("Master pointer for %s", tablet->name);
master = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
@@ -2910,8 +2892,6 @@ tablet_handle_done (void *data,
"display", display,
"device-manager", device_manager,
"seat", seat,
"vendor-id", vid,
"product-id", pid,
NULL);
eraser_device = g_object_new (GDK_TYPE_WAYLAND_DEVICE,
@@ -2923,8 +2903,6 @@ tablet_handle_done (void *data,
"display", display,
"device-manager", device_manager,
"seat", seat,
"vendor-id", vid,
"product-id", pid,
NULL);
tablet->master = master;
@@ -2948,8 +2926,6 @@ tablet_handle_done (void *data,
g_free (eraser_name);
g_free (master_name);
g_free (vid);
g_free (pid);
}
static void
@@ -3446,9 +3422,6 @@ gdk_wayland_tablet_flush_frame_event (GdkWaylandTabletData *tablet,
sizeof (gdouble) *
gdk_device_get_n_axes (tablet->current_device));
break;
case GDK_SCROLL:
event->scroll.time = time;
break;
case GDK_PROXIMITY_IN:
case GDK_PROXIMITY_OUT:
event->proximity.time = time;
@@ -3637,7 +3610,6 @@ tablet_tool_handle_proximity_out (void *data,
tablet->pointer_info.focus = NULL;
gdk_device_update_tool (tablet->current_device, NULL);
g_clear_object (&tablet->pointer_info.cursor);
}
static void
@@ -3871,32 +3843,7 @@ tablet_tool_handle_wheel (void *data,
int32_t degrees,
int32_t clicks)
{
GdkWaylandTabletToolData *tool = data;
GdkWaylandTabletData *tablet = tool->current_tablet;
GdkWaylandSeat *seat = GDK_WAYLAND_SEAT (tablet->seat);
GdkEvent *event;
GDK_NOTE (EVENTS,
g_message ("tablet tool %d wheel %d/%d",
gdk_device_tool_get_tool_type (tool->tool), degrees, clicks));
if (clicks == 0)
return;
/* Send smooth event */
event = create_scroll_event (seat, &tablet->pointer_info,
tablet->master, tablet->current_device, FALSE);
gdk_event_set_device_tool (event, tablet->current_tool->tool);
event->scroll.direction = GDK_SCROLL_SMOOTH;
event->scroll.delta_y = clicks;
_gdk_wayland_display_deliver_event (seat->display, event);
/* Send discrete event */
event = create_scroll_event (seat, &tablet->pointer_info,
tablet->master, tablet->current_device, TRUE);
gdk_event_set_device_tool (event, tablet->current_tool->tool);
event->scroll.direction = (clicks > 0) ? GDK_SCROLL_DOWN : GDK_SCROLL_UP;
_gdk_wayland_display_deliver_event (seat->display, event);
/* FIXME: Handle wheel */
}
static void
@@ -4761,10 +4708,6 @@ gdk_wayland_seat_grab (GdkSeat *seat,
_gdk_display_get_next_serial (display),
evtime,
FALSE);
/* Inhibit shortcuts if the seat grab is for the keyboard only */
if (capabilities == GDK_SEAT_CAPABILITY_KEYBOARD)
gdk_wayland_window_inhibit_shortcuts (window, seat);
}
if (wayland_seat->tablets &&
@@ -4836,11 +4779,7 @@ gdk_wayland_seat_ungrab (GdkSeat *seat)
grab = _gdk_display_get_last_device_grab (display, wayland_seat->master_keyboard);
if (grab)
{
grab->serial_end = grab->serial_start;
if (grab->window)
gdk_wayland_window_restore_shortcuts (grab->window, seat);
}
grab->serial_end = grab->serial_start;
}
if (wayland_seat->touch_master)
@@ -4898,19 +4837,6 @@ gdk_wayland_seat_get_slaves (GdkSeat *seat,
if (wayland_seat->touch && (capabilities & GDK_SEAT_CAPABILITY_TOUCH))
slaves = g_list_prepend (slaves, wayland_seat->touch);
if (wayland_seat->tablets && (capabilities & GDK_SEAT_CAPABILITY_TABLET_STYLUS))
{
GList *l;
for (l = wayland_seat->tablets; l; l = l->next)
{
GdkWaylandTabletData *tablet = l->data;
slaves = g_list_prepend (slaves, tablet->stylus_device);
slaves = g_list_prepend (slaves, tablet->eraser_device);
}
}
return slaves;
}
@@ -5114,25 +5040,9 @@ _gdk_wayland_device_get_implicit_grab_serial (GdkWaylandDevice *device,
if (sequence)
touch = gdk_wayland_seat_get_touch (GDK_WAYLAND_SEAT (seat),
GDK_EVENT_SEQUENCE_TO_SLOT (sequence));
if (touch)
return touch->touch_down_serial;
if (event)
{
GdkDevice *source = gdk_event_get_source_device (event);
GdkWaylandSeat *wayland_seat = GDK_WAYLAND_SEAT (seat);
GList *l;
for (l = wayland_seat->tablets; l; l = l->next)
{
GdkWaylandTabletData *tablet = l->data;
if (tablet->current_device == source)
return tablet->pointer_info.press_serial;
}
}
else
return GDK_WAYLAND_SEAT (seat)->pointer_info.press_serial;
}
@@ -5143,7 +5053,6 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
GdkWaylandSeat *wayland_seat;
GdkWaylandTouchData *touch;
GHashTableIter iter;
GList *l;
uint32_t serial;
wayland_seat = GDK_WAYLAND_SEAT (seat);
@@ -5157,14 +5066,6 @@ _gdk_wayland_seat_get_last_implicit_grab_serial (GdkSeat *seat,
if (wayland_seat->pointer_info.press_serial > serial)
serial = wayland_seat->pointer_info.press_serial;
for (l = wayland_seat->tablets; l; l = l->next)
{
GdkWaylandTabletData *tablet = l->data;
if (tablet->pointer_info.press_serial > serial)
serial = tablet->pointer_info.press_serial;
}
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &touch))
{
if (touch->touch_down_serial > serial)
+3 -31
View File
@@ -83,8 +83,6 @@
* ]|
*/
#define MIN_SYSTEM_BELL_DELAY_MS 20
static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland);
G_DEFINE_TYPE (GdkWaylandDisplay, gdk_wayland_display, GDK_TYPE_DISPLAY)
@@ -451,12 +449,6 @@ gdk_registry_handle_global (void *data,
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_importer_v1_interface, 1);
}
else if (strcmp (interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0)
{
display_wayland->keyboard_shortcuts_inhibit =
wl_registry_bind (display_wayland->wl_registry, id,
&zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
}
else
handled = FALSE;
@@ -668,13 +660,10 @@ gdk_wayland_display_get_default_screen (GdkDisplay *display)
return GDK_WAYLAND_DISPLAY (display)->screen;
}
void
gdk_wayland_display_system_bell (GdkDisplay *display,
GdkWindow *window)
static void
gdk_wayland_display_beep (GdkDisplay *display)
{
GdkWaylandDisplay *display_wayland;
struct gtk_surface1 *gtk_surface;
gint64 now_ms;
g_return_if_fail (GDK_IS_DISPLAY (display));
@@ -683,24 +672,7 @@ gdk_wayland_display_system_bell (GdkDisplay *display,
if (!display_wayland->gtk_shell)
return;
if (window)
gtk_surface = gdk_wayland_window_get_gtk_surface (window);
else
gtk_surface = NULL;
now_ms = g_get_monotonic_time () / 1000;
if (now_ms - display_wayland->last_bell_time_ms < MIN_SYSTEM_BELL_DELAY_MS)
return;
display_wayland->last_bell_time_ms = now_ms;
gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface);
}
static void
gdk_wayland_display_beep (GdkDisplay *display)
{
gdk_wayland_display_system_bell (display, NULL);
gtk_shell1_system_bell (display_wayland->gtk_shell, NULL);
}
static void
-4
View File
@@ -31,7 +31,6 @@
#include <gdk/wayland/gtk-shell-client-protocol.h>
#include <gdk/wayland/xdg-shell-unstable-v6-client-protocol.h>
#include <gdk/wayland/xdg-foreign-unstable-v1-client-protocol.h>
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
@@ -78,7 +77,6 @@ struct _GdkWaylandDisplay
struct zwp_tablet_manager_v2 *tablet_manager;
struct zxdg_exporter_v1 *xdg_exporter;
struct zxdg_importer_v1 *xdg_importer;
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
GList *async_roundtrips;
@@ -112,8 +110,6 @@ struct _GdkWaylandDisplay
GPtrArray *monitors;
gint64 last_bell_time_ms;
/* egl info */
EGLDisplay egl_display;
int egl_major_version;
-10
View File
@@ -83,9 +83,6 @@ void _gdk_wayland_display_get_maximal_cursor_size (GdkDisplay *display,
gboolean _gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display);
gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display);
void gdk_wayland_display_system_bell (GdkDisplay *display,
GdkWindow *window);
struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkCursor *cursor,
guint image_index,
int *hotspot_x,
@@ -274,16 +271,9 @@ EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window,
EGLSurface gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window,
EGLConfig config);
struct gtk_surface1 * gdk_wayland_window_get_gtk_surface (GdkWindow *window);
void gdk_wayland_seat_set_global_cursor (GdkSeat *seat,
GdkCursor *cursor);
struct wl_output *gdk_wayland_window_get_wl_output (GdkWindow *window);
void gdk_wayland_window_inhibit_shortcuts (GdkWindow *window,
GdkSeat *gdk_seat);
void gdk_wayland_window_restore_shortcuts (GdkWindow *window,
GdkSeat *gdk_seat);
#endif /* __GDK_PRIVATE_WAYLAND_H__ */
+9 -60
View File
@@ -204,7 +204,6 @@ struct _GdkWindowImplWayland
} exported;
struct zxdg_imported_v1 *imported_transient_for;
GHashTable *shortcuts_inhibitors;
};
struct _GdkWindowImplWaylandClass
@@ -669,7 +668,6 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
window->impl = GDK_WINDOW_IMPL (impl);
impl->wrapper = GDK_WINDOW (window);
impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
if (window->width > 65535)
{
@@ -938,8 +936,15 @@ gdk_wayland_window_sync (GdkWindow *window)
static gboolean
gdk_window_impl_wayland_beep (GdkWindow *window)
{
gdk_wayland_display_system_bell (gdk_window_get_display (window),
window);
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandDisplay *display_wayland =
GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
if (!display_wayland->gtk_shell)
return FALSE;
gtk_shell1_system_bell (display_wayland->gtk_shell,
impl->display_server.gtk_surface);
return TRUE;
}
@@ -970,8 +975,6 @@ gdk_window_impl_wayland_finalize (GObject *object)
g_clear_pointer (&impl->input_region, cairo_region_destroy);
g_clear_pointer (&impl->staged_updates_region, cairo_region_destroy);
g_hash_table_destroy (impl->shortcuts_inhibitors);
G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
}
@@ -3819,13 +3822,6 @@ gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window,
return impl->dummy_egl_surface;
}
struct gtk_surface1 *
gdk_wayland_window_get_gtk_surface (GdkWindow *window)
{
g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL);
return GDK_WINDOW_IMPL_WAYLAND (window->impl)->display_server.gtk_surface;
}
/**
* gdk_wayland_window_set_use_custom_surface:
@@ -4167,50 +4163,3 @@ gdk_wayland_window_set_transient_for_exported (GdkWindow *window,
return TRUE;
}
static struct zwp_keyboard_shortcuts_inhibitor_v1 *
gdk_wayland_window_get_inhibitor (GdkWindowImplWayland *impl,
struct wl_seat *seat)
{
return g_hash_table_lookup (impl->shortcuts_inhibitors, seat);
}
void
gdk_wayland_window_inhibit_shortcuts (GdkWindow *window,
GdkSeat *gdk_seat)
{
GdkWindowImplWayland *impl= GDK_WINDOW_IMPL_WAYLAND (window->impl);
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
struct wl_surface *surface = impl->display_server.wl_surface;
struct wl_seat *seat = gdk_wayland_seat_get_wl_seat (gdk_seat);
struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor;
if (display->keyboard_shortcuts_inhibit == NULL)
return;
if (gdk_wayland_window_get_inhibitor (impl, seat))
return; /* Already inhibitted */
inhibitor =
zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts (
display->keyboard_shortcuts_inhibit, surface, seat);
g_hash_table_insert (impl->shortcuts_inhibitors, seat, inhibitor);
}
void
gdk_wayland_window_restore_shortcuts (GdkWindow *window,
GdkSeat *gdk_seat)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
struct wl_seat *seat = gdk_wayland_seat_get_wl_seat (gdk_seat);
struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor;
inhibitor = gdk_wayland_window_get_inhibitor (impl, seat);
if (inhibitor == NULL)
return; /* Not inhibitted */
zwp_keyboard_shortcuts_inhibitor_v1_destroy (inhibitor);
g_hash_table_remove (impl->shortcuts_inhibitors, seat);
}
-1
View File
@@ -54,7 +54,6 @@ proto_sources = [
['xdg-shell', 'unstable', 'v6', ],
['xdg-foreign', 'unstable', 'v1', ],
['tablet', 'unstable', 'v2', ],
[ 'keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
]
gdk_wayland_gen_headers = []
-2
View File
@@ -433,8 +433,6 @@ create_device (GdkDeviceManager *device_manager,
input_source = GDK_SOURCE_ERASER;
else if (strstr (tmp_name, "cursor"))
input_source = GDK_SOURCE_CURSOR;
else if (strstr (tmp_name, " pad"))
input_source = GDK_SOURCE_TABLET_PAD;
else if (strstr (tmp_name, "wacom") ||
strstr (tmp_name, "pen"))
input_source = GDK_SOURCE_PEN;
+1 -1
View File
@@ -173,7 +173,7 @@ _gdk_x11_window_get_toplevel (GdkWindow *window)
if (!impl->toplevel)
{
impl->toplevel = g_new0 (GdkToplevelX11, 1);
impl->toplevel->have_focused = FALSE;
impl->toplevel->have_focused = TRUE;
}
return impl->toplevel;
-1
View File
@@ -2558,7 +2558,6 @@ gsk_color_matrix_node_draw (GskRenderNode *node,
cairo_paint (cr);
cairo_restore (cr);
cairo_pattern_destroy (pattern);
}
#define GSK_COLOR_MATRIX_NODE_VARIANT_TYPE "(dddddddddddddddddddduv)"
+19 -14
View File
@@ -164,7 +164,6 @@ gtk_public_h_sources = \
gtkcellrenderertext.h \
gtkcellrenderertoggle.h \
gtkcellview.h \
gtkcenterbox.h \
gtkcheckbutton.h \
gtkcheckmenuitem.h \
gtkclipboard.h \
@@ -189,6 +188,7 @@ gtk_public_h_sources = \
gtkentrybuffer.h \
gtkentrycompletion.h \
gtkenums.h \
gtkeventbox.h \
gtkeventcontroller.h \
gtkexpander.h \
gtkfilechooser.h \
@@ -373,7 +373,9 @@ gtk_private_h_sources = \
gtkbitmaskprivateimpl.h \
gtkbookmarksmanager.h \
gtkboxprivate.h \
gtkboxgadgetprivate.h \
gtkbuilderprivate.h \
gtkbuiltiniconprivate.h \
gtkbuttonprivate.h \
gtkcellareaboxcontextprivate.h \
gtkcheckbuttonprivate.h \
@@ -395,10 +397,12 @@ gtk_private_h_sources = \
gtkcsscalcvalueprivate.h \
gtkcsscolorvalueprivate.h \
gtkcsscornervalueprivate.h \
gtkcsscustomgadgetprivate.h \
gtkcssdimensionvalueprivate.h \
gtkcsseasevalueprivate.h \
gtkcssenumvalueprivate.h \
gtkcssfiltervalueprivate.h \
gtkcssgadgetprivate.h \
gtkcssiconthemevalueprivate.h \
gtkcssimagebuiltinprivate.h \
gtkcssimagecrossfadeprivate.h \
@@ -458,7 +462,6 @@ gtk_private_h_sources = \
gtkfilechooserprivate.h \
gtkfilechoosernativeprivate.h \
gtkfilechooserwidgetprivate.h \
gtkfilechoosererrorstackprivate.h \
gtkfilechooserutils.h \
gtkfilefilterprivate.h \
gtkfilesystem.h \
@@ -574,7 +577,8 @@ gtk_private_h_sources = \
gtkwindowprivate.h \
gtktreemenu.h \
gdkpixbufutilsprivate.h \
gtkgizmoprivate.h
gtkgizmoprivate.h \
gtkcenterboxprivate.h
# GTK+ C sources to build the library from
gtk_base_c_sources = \
@@ -617,10 +621,12 @@ gtk_base_c_sources = \
gtkbookmarksmanager.c \
gtkborder.c \
gtkbox.c \
gtkboxgadget.c \
gtkbuildable.c \
gtkbuilder.c \
gtkbuilderparser.c \
gtkbuilder-menus.c \
gtkbuiltinicon.c \
gtkbutton.c \
gtkcalendar.c \
gtkcellarea.c \
@@ -662,10 +668,12 @@ gtk_base_c_sources = \
gtkcsscalcvalue.c \
gtkcsscolorvalue.c \
gtkcsscornervalue.c \
gtkcsscustomgadget.c \
gtkcssdimensionvalue.c \
gtkcsseasevalue.c \
gtkcssenumvalue.c \
gtkcssfiltervalue.c \
gtkcssgadget.c \
gtkcssiconthemevalue.c \
gtkcssimage.c \
gtkcssimagebuiltin.c \
@@ -725,6 +733,7 @@ gtk_base_c_sources = \
gtkentry.c \
gtkentrybuffer.c \
gtkentrycompletion.c \
gtkeventbox.c \
gtkeventcontroller.c \
gtkexpander.c \
gtkfilechooser.c \
@@ -934,8 +943,7 @@ gtk_base_c_sources = \
gtkwin32theme.c \
gdkpixbufutils.c \
gtkgizmo.c \
gtkcenterbox.c \
gtkfilechoosererrorstack.c
gtkcenterbox.c
if USE_QUARTZ
gtk_base_c_sources += \
@@ -1017,7 +1025,6 @@ gtk_use_quartz_c_sources = \
gtkmountoperation-stub.c \
gtkapplication-quartz.c \
gtkapplication-quartz-menu.c \
gtkfilechoosernativequartz.c \
gtkquartz.c
gtk_use_stub_c_sources = \
gtkmountoperation-stub.c
@@ -1189,21 +1196,19 @@ gtkmarshalers.h: stamp-gtkmarshalers.h
@true
stamp-gtkmarshalers.h: gtkmarshalers.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
--header \
--prefix=_gtk_marshal \
--header \
--valist-marshallers \
$(srcdir)/gtkmarshalers.list > xgen-gmlh \
$(srcdir)/gtkmarshalers.list >> xgen-gmlh \
&& (cmp -s xgen-gmlh gtkmarshalers.h || cp xgen-gmlh gtkmarshalers.h) \
&& rm -f xgen-gmlh \
&& echo timestamp > $(@F)
gtkmarshalers.c: gtkmarshalers.list
$(AM_V_GEN) $(GLIB_GENMARSHAL) \
$(AM_V_GEN) (echo "#undef G_ENABLE_DEBUG"; \
$(GLIB_GENMARSHAL) \
--prefix=_gtk_marshal \
--body \
--prefix=_gtk_marshal \
--valist-marshallers \
--include-header="gtkmarshalers.h" \
-U G_ENABLE_DEBUG \
$(srcdir)/gtkmarshalers.list > xgen-gmlc \
--valist-marshallers $(srcdir)/gtkmarshalers.list) >> xgen-gmlc \
&& cp xgen-gmlc gtkmarshalers.c \
&& rm -f xgen-gmlc
+1 -1
View File
@@ -28,7 +28,7 @@ struct _GtkSpinButtonAccessiblePrivate
static void atk_value_interface_init (AtkValueIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkSpinButtonAccessible, gtk_spin_button_accessible, GTK_TYPE_WIDGET_ACCESSIBLE,
G_DEFINE_TYPE_WITH_CODE (GtkSpinButtonAccessible, gtk_spin_button_accessible, GTK_TYPE_ENTRY_ACCESSIBLE,
G_ADD_PRIVATE (GtkSpinButtonAccessible)
G_IMPLEMENT_INTERFACE (ATK_TYPE_VALUE, atk_value_interface_init))
+30 -1
View File
@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
#include <gtk/gtkeventbox.h>
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkmenu.h>
@@ -91,6 +92,33 @@ gtk_toplevel_accessible_get_name (AtkObject *obj)
return g_get_prgname ();
}
static gboolean
is_combo_window (GtkWidget *widget)
{
GtkWidget *child;
AtkObject *obj;
child = gtk_bin_get_child (GTK_BIN (widget));
if (!GTK_IS_EVENT_BOX (child))
return FALSE;
child = gtk_bin_get_child (GTK_BIN (child));
if (!GTK_IS_FRAME (child))
return FALSE;
child = gtk_bin_get_child (GTK_BIN (child));
if (!GTK_IS_SCROLLED_WINDOW (child))
return FALSE;
obj = gtk_widget_get_accessible (child);
obj = atk_object_get_parent (obj);
return FALSE;
}
static gboolean
is_attached_menu_window (GtkWidget *widget)
{
@@ -178,7 +206,8 @@ show_event_watcher (GSignalInvocationHint *ihint,
widget = GTK_WIDGET (object);
if (gtk_widget_get_parent (widget) ||
is_attached_menu_window (widget))
is_attached_menu_window (widget) ||
is_combo_window (widget))
return TRUE;
child = gtk_widget_get_accessible (widget);
+4 -4
View File
@@ -1032,10 +1032,10 @@ gtk_tree_view_accessible_get_cell_area (GtkCellAccessibleParent *parent,
expander_column = gtk_tree_view_get_expander_column (tree_view);
if (expander_column == tv_col)
{
/* Values from gtktreeview.c ... */
#define _TREE_VIEW_EXPANDER_SIZE 16
#define _TREE_VIEW_HORIZONTAL_SEPARATOR 4
gint expander_size = _TREE_VIEW_EXPANDER_SIZE + (_TREE_VIEW_HORIZONTAL_SEPARATOR / 2);
gint expander_size;
gtk_widget_style_get (widget,
"expander-size", &expander_size,
NULL);
cell_rect->x += expander_size + EXTRA_EXPANDER_PADDING;
cell_rect->width -= expander_size + EXTRA_EXPANDER_PADDING;
}
+1
View File
@@ -68,6 +68,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEditable, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEntry, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEntryBuffer, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEntryCompletion, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEventBox, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkEventController, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkExpander, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkFileChooserButton, g_object_unref)
+1
View File
@@ -93,6 +93,7 @@
#include <gtk/gtkentrybuffer.h>
#include <gtk/gtkentrycompletion.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkeventbox.h>
#include <gtk/gtkeventcontroller.h>
#include <gtk/gtkexpander.h>
#include <gtk/gtkfixed.h>
+12 -12
View File
@@ -112,18 +112,18 @@ typedef struct
static const LicenseInfo gtk_license_info [] = {
{ N_("License"), NULL },
{ N_("Custom License") , NULL },
{ N_("GNU General Public License, version 2 or later"), "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html" },
{ N_("GNU General Public License, version 3 or later"), "https://www.gnu.org/licenses/gpl-3.0.html" },
{ N_("GNU Lesser General Public License, version 2.1 or later"), "https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" },
{ N_("GNU Lesser General Public License, version 3 or later"), "https://www.gnu.org/licenses/lgpl-3.0.html" },
{ N_("BSD 2-Clause License"), "https://opensource.org/licenses/bsd-license.php" },
{ N_("The MIT License (MIT)"), "https://opensource.org/licenses/mit-license.php" },
{ N_("Artistic License 2.0"), "https://opensource.org/licenses/artistic-license-2.0.php" },
{ N_("GNU General Public License, version 2 only"), "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html" },
{ N_("GNU General Public License, version 3 only"), "https://www.gnu.org/licenses/gpl-3.0.html" },
{ N_("GNU Lesser General Public License, version 2.1 only"), "https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" },
{ N_("GNU Lesser General Public License, version 3 only"), "https://www.gnu.org/licenses/lgpl-3.0.html" },
{ N_("GNU Affero General Public License, version 3 or later"), "https://www.gnu.org/licenses/agpl-3.0.html" }
{ N_("GNU General Public License, version 2 or later"), "http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" },
{ N_("GNU General Public License, version 3 or later"), "http://www.gnu.org/licenses/gpl-3.0.html" },
{ N_("GNU Lesser General Public License, version 2.1 or later"), "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" },
{ N_("GNU Lesser General Public License, version 3 or later"), "http://www.gnu.org/licenses/lgpl-3.0.html" },
{ N_("BSD 2-Clause License"), "http://opensource.org/licenses/bsd-license.php" },
{ N_("The MIT License (MIT)"), "http://opensource.org/licenses/mit-license.php" },
{ N_("Artistic License 2.0"), "http://opensource.org/licenses/artistic-license-2.0.php" },
{ N_("GNU General Public License, version 2 only"), "http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" },
{ N_("GNU General Public License, version 3 only"), "http://www.gnu.org/licenses/gpl-3.0.html" },
{ N_("GNU Lesser General Public License, version 2.1 only"), "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" },
{ N_("GNU Lesser General Public License, version 3 only"), "http://www.gnu.org/licenses/lgpl-3.0.html" },
{ N_("GNU Affero General Public License, version 3 or later"), "http://www.gnu.org/licenses/agpl-3.0.html" }
};
typedef struct
+160 -162
View File
@@ -40,7 +40,6 @@
#include "gtkwidgetprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkbox.h"
/**
* SECTION:gtkaccellabel
@@ -49,7 +48,7 @@
* @See_also: #GtkAccelGroup
*
* The #GtkAccelLabel widget is a subclass of #GtkLabel that also displays an
* accelerator key on the right of the label text, e.g. Ctrl+S.
* accelerator key on the right of the label text, e.g. Ctl+S.
* It is commonly used in menus to show the keyboard short-cuts for commands.
*
* The accelerator key to display is typically not set explicitly (although it
@@ -58,10 +57,10 @@
* set by calling gtk_accel_label_set_accel_widget().
*
* For example, a #GtkMenuItem widget may have an accelerator added to emit
* the activate signal when the Ctrl+S key combination is pressed.
* the activate signal when the Ctl+S key combination is pressed.
* A #GtkAccelLabel is created and added to the #GtkMenuItem, and
* gtk_accel_label_set_accel_widget() is called with the #GtkMenuItem as the
* second argument. The #GtkAccelLabel will now display Ctrl+S after its label.
* second argument. The #GtkAccelLabel will now display Ctl+S after its label.
*
* Note that creating a #GtkMenuItem with gtk_menu_item_new_with_label() (or
* one of the similar functions for #GtkCheckMenuItem and #GtkRadioMenuItem)
@@ -100,34 +99,30 @@
* # CSS nodes
*
* |[<!-- language="plain" -->
* accellabel
* box
* label
* accelerator
* label
* accelerator
* ]|
*
* #GtkAccelLabel has a main CSS node with the name accellabel.
* It adds a subnode with name label and another one with name accelerator.
* Like #GtkLabel, GtkAccelLabel has a main CSS node with the name label.
* It adds a subnode with name accelerator.
*/
enum {
PROP_0,
PROP_ACCEL_CLOSURE,
PROP_ACCEL_WIDGET,
PROP_LABEL,
PROP_USE_UNDERLINE,
LAST_PROP
};
struct _GtkAccelLabelPrivate
{
GtkWidget *box;
GtkWidget *text_label;
GtkWidget *accel_label;
GtkWidget *accel_widget; /* done */
GClosure *accel_closure; /* has set function */
GtkAccelGroup *accel_group; /* set by set_accel_closure() */
gchar *accel_string; /* has set function */
GtkCssNode *accel_node;
guint accel_padding; /* should be style property? */
guint16 accel_string_width; /* seems to be private */
guint accel_key; /* manual accel key specification if != 0 */
GdkModifierType accel_mods;
@@ -147,6 +142,7 @@ static void gtk_accel_label_destroy (GtkWidget *widget);
static void gtk_accel_label_finalize (GObject *object);
static void gtk_accel_label_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static const gchar *gtk_accel_label_get_string (GtkAccelLabel *accel_label);
static void gtk_accel_label_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
@@ -156,19 +152,7 @@ static void gtk_accel_label_measure (GtkWidget *widget,
int *natural_baseline);
G_DEFINE_TYPE_WITH_PRIVATE (GtkAccelLabel, gtk_accel_label, GTK_TYPE_WIDGET)
static void
gtk_accel_label_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
GtkAccelLabel *al = GTK_ACCEL_LABEL (widget);
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (al);
gtk_widget_size_allocate (priv->box, allocation, baseline, out_clip);
}
G_DEFINE_TYPE_WITH_PRIVATE (GtkAccelLabel, gtk_accel_label, GTK_TYPE_LABEL)
static void
gtk_accel_label_class_init (GtkAccelLabelClass *class)
@@ -180,9 +164,8 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
gobject_class->set_property = gtk_accel_label_set_property;
gobject_class->get_property = gtk_accel_label_get_property;
widget_class->measure = gtk_accel_label_measure;
widget_class->size_allocate = gtk_accel_label_size_allocate;
widget_class->snapshot = gtk_accel_label_snapshot;
widget_class->measure = gtk_accel_label_measure;
widget_class->destroy = gtk_accel_label_destroy;
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_ACCEL_LABEL);
@@ -236,23 +219,7 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
GTK_TYPE_WIDGET,
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
props[PROP_LABEL] =
g_param_spec_string ("label",
P_("Label"),
P_("The text displayed next to the accelerator"),
"",
GTK_PARAM_READWRITE);
props[PROP_USE_UNDERLINE] =
g_param_spec_boolean ("use-underline",
P_("Use underline"),
P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (gobject_class, LAST_PROP, props);
gtk_widget_class_set_css_name (widget_class, "accellabel");
}
static void
@@ -273,12 +240,6 @@ gtk_accel_label_set_property (GObject *object,
case PROP_ACCEL_WIDGET:
gtk_accel_label_set_accel_widget (accel_label, g_value_get_object (value));
break;
case PROP_LABEL:
gtk_accel_label_set_label (accel_label, g_value_get_string (value));
break;
case PROP_USE_UNDERLINE:
gtk_accel_label_set_use_underline (accel_label, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -303,44 +264,45 @@ gtk_accel_label_get_property (GObject *object,
case PROP_ACCEL_WIDGET:
g_value_set_object (value, accel_label->priv->accel_widget);
break;
case PROP_LABEL:
g_value_set_string (value, gtk_accel_label_get_label (accel_label));
break;
case PROP_USE_UNDERLINE:
g_value_set_boolean (value, gtk_accel_label_get_use_underline (accel_label));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
node_style_changed_cb (GtkCssNode *node,
GtkCssStyleChange *change,
GtkWidget *widget)
{
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE | GTK_CSS_AFFECTS_CLIP))
gtk_widget_queue_resize (widget);
else
gtk_widget_queue_draw (widget);
}
static void
gtk_accel_label_init (GtkAccelLabel *accel_label)
{
GtkAccelLabelPrivate *priv;
gtk_widget_set_has_window (GTK_WIDGET (accel_label), FALSE);
GtkCssNode *widget_node;
accel_label->priv = gtk_accel_label_get_instance_private (accel_label);
priv = accel_label->priv;
priv->accel_padding = 3;
priv->accel_widget = NULL;
priv->accel_closure = NULL;
priv->accel_group = NULL;
priv->accel_string = NULL;
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
priv->text_label = gtk_label_new ("");
gtk_widget_set_hexpand (priv->text_label, TRUE);
gtk_label_set_xalign (GTK_LABEL (priv->text_label), 0.0f);
priv->accel_label = g_object_new (GTK_TYPE_LABEL,
"css-name", "accelerator",
NULL);
gtk_container_add (GTK_CONTAINER (priv->box), priv->text_label);
gtk_container_add (GTK_CONTAINER (priv->box), priv->accel_label);
gtk_widget_set_parent (priv->box, GTK_WIDGET (accel_label));
widget_node = gtk_widget_get_css_node (GTK_WIDGET (accel_label));
priv->accel_node = gtk_css_node_new ();
gtk_css_node_set_name (priv->accel_node, I_("accelerator"));
gtk_css_node_set_parent (priv->accel_node, widget_node);
gtk_css_node_set_state (priv->accel_node, gtk_css_node_get_state (widget_node));
g_signal_connect_object (priv->accel_node, "style-changed", G_CALLBACK (node_style_changed_cb), accel_label, 0);
g_object_unref (priv->accel_node);
}
/**
@@ -360,7 +322,7 @@ gtk_accel_label_new (const gchar *string)
accel_label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL);
gtk_label_set_label (GTK_LABEL (accel_label->priv->text_label), string);
gtk_label_set_text (GTK_LABEL (accel_label), string);
return GTK_WIDGET (accel_label);
}
@@ -381,7 +343,7 @@ gtk_accel_label_finalize (GObject *object)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (object);
gtk_widget_unparent (accel_label->priv->box);
g_free (accel_label->priv->accel_string);
G_OBJECT_CLASS (gtk_accel_label_parent_class)->finalize (object);
}
@@ -416,15 +378,41 @@ gtk_accel_label_get_accel_widget (GtkAccelLabel *accel_label)
guint
gtk_accel_label_get_accel_width (GtkAccelLabel *accel_label)
{
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
int min;
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), 0);
gtk_widget_measure (priv->accel_label, GTK_ORIENTATION_HORIZONTAL, -1,
&min, NULL, NULL, NULL);
return (accel_label->priv->accel_string_width +
(accel_label->priv->accel_string_width ? accel_label->priv->accel_padding : 0));
}
return min;
static PangoLayout *
gtk_accel_label_get_accel_layout (GtkAccelLabel *accel_label)
{
GtkWidget *widget = GTK_WIDGET (accel_label);
GtkStyleContext *context;
PangoAttrList *attrs;
PangoLayout *layout;
PangoFontDescription *font_desc;
context = gtk_widget_get_style_context (widget);
gtk_style_context_save_to_node (context, accel_label->priv->accel_node);
layout = gtk_widget_create_pango_layout (widget, gtk_accel_label_get_string (accel_label));
attrs = _gtk_style_context_get_pango_attributes (context);
if (!attrs)
attrs = pango_attr_list_new ();
gtk_style_context_get (context,
"font", &font_desc,
NULL);
pango_attr_list_change (attrs, pango_attr_font_desc_new (font_desc));
pango_font_description_free (font_desc);
pango_layout_set_attributes (layout, attrs);
pango_attr_list_unref (attrs);
gtk_style_context_restore (context);
return layout;
}
static void
@@ -437,11 +425,37 @@ gtk_accel_label_measure (GtkWidget *widget,
int *natural_baseline)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (widget);
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
gtk_widget_measure (priv->box, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->measure (widget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
PangoLayout *layout;
int width;
layout = gtk_accel_label_get_accel_layout (accel_label);
pango_layout_get_pixel_size (layout, &width, NULL);
accel_label->priv->accel_string_width = width;
g_object_unref (layout);
}
}
static gint
get_first_baseline (PangoLayout *layout)
{
PangoLayoutIter *iter;
gint result;
iter = pango_layout_get_iter (layout);
result = pango_layout_iter_get_baseline (iter);
pango_layout_iter_free (iter);
return PANGO_PIXELS (result);
}
static void
@@ -449,9 +463,44 @@ gtk_accel_label_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (widget);
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
guint ac_width;
GtkAllocation allocation;
GtkRequisition requisition;
gtk_widget_snapshot_child (widget, priv->box, snapshot);
GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->snapshot (widget, snapshot);
ac_width = gtk_accel_label_get_accel_width (accel_label);
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_get_preferred_size (widget, NULL, &requisition);
if (allocation.width >= requisition.width + ac_width)
{
GtkStyleContext *context;
PangoLayout *label_layout;
PangoLayout *accel_layout;
gint x;
gint y;
context = gtk_widget_get_style_context (widget);
label_layout = gtk_label_get_layout (GTK_LABEL (accel_label));
accel_layout = gtk_accel_label_get_accel_layout (accel_label);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
x = 0;
else
x = gtk_widget_get_allocated_width (widget) - ac_width;
gtk_label_get_layout_offsets (GTK_LABEL (accel_label), NULL, &y);
y += get_first_baseline (label_layout) - get_first_baseline (accel_layout) - allocation.y;
gtk_style_context_save_to_node (context, accel_label->priv->accel_node);
gtk_snapshot_render_layout (snapshot, context, x, y, accel_layout);
gtk_style_context_restore (context);
g_object_unref (accel_layout);
}
}
static void
@@ -491,17 +540,15 @@ accel_widget_weak_ref_cb (GtkAccelLabel *accel_label,
/**
* gtk_accel_label_set_accel_widget:
* @accel_label: a #GtkAccelLabel
* @accel_widget: (nullable): the widget to be monitored, or %NULL
* @accel_widget: the widget to be monitored.
*
* Sets the widget to be monitored by this accelerator label. Passing %NULL for
* @accel_widget will dissociate @accel_label from its current widget, if any.
* Sets the widget to be monitored by this accelerator label.
*/
void
gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
GtkWidget *accel_widget)
{
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
if (accel_widget)
g_return_if_fail (GTK_IS_WIDGET (accel_widget));
@@ -516,9 +563,7 @@ gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
g_object_weak_unref (G_OBJECT (accel_label->priv->accel_widget),
(GWeakNotify) accel_widget_weak_ref_cb, accel_label);
}
accel_label->priv->accel_widget = accel_widget;
if (accel_label->priv->accel_widget)
{
g_object_weak_ref (G_OBJECT (accel_label->priv->accel_widget),
@@ -528,7 +573,6 @@ gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
accel_label, G_CONNECT_SWAPPED);
refetch_widget_accel_closure (accel_label);
}
g_object_notify_by_pspec (G_OBJECT (accel_label), props[PROP_ACCEL_WIDGET]);
}
}
@@ -536,7 +580,9 @@ gtk_accel_label_set_accel_widget (GtkAccelLabel *accel_label,
static void
gtk_accel_label_reset (GtkAccelLabel *accel_label)
{
gtk_accel_label_refetch (accel_label);
g_clear_pointer (&accel_label->priv->accel_string, g_free);
gtk_widget_queue_resize (GTK_WIDGET (accel_label));
}
static void
@@ -553,20 +599,16 @@ check_accel_changed (GtkAccelGroup *accel_group,
/**
* gtk_accel_label_set_accel_closure:
* @accel_label: a #GtkAccelLabel
* @accel_closure: (nullable): the closure to monitor for accelerator changes,
* or %NULL
* @accel_closure: the closure to monitor for accelerator changes.
*
* Sets the closure to be monitored by this accelerator label. The closure
* must be connected to an accelerator group; see gtk_accel_group_connect().
* Passing %NULL for @accel_closure will dissociate @accel_label from its
* current closure, if any.
**/
void
gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
GClosure *accel_closure)
{
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
if (accel_closure)
g_return_if_fail (gtk_accel_group_from_accel_closure (accel_closure) != NULL);
@@ -580,9 +622,7 @@ gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
accel_label->priv->accel_group = NULL;
g_closure_unref (accel_label->priv->accel_closure);
}
accel_label->priv->accel_closure = accel_closure;
if (accel_label->priv->accel_closure)
{
g_closure_ref (accel_label->priv->accel_closure);
@@ -591,7 +631,6 @@ gtk_accel_label_set_accel_closure (GtkAccelLabel *accel_label,
G_CALLBACK (check_accel_changed),
accel_label, 0);
}
gtk_accel_label_reset (accel_label);
g_object_notify_by_pspec (G_OBJECT (accel_label), props[PROP_ACCEL_CLOSURE]);
}
@@ -605,6 +644,15 @@ find_accel (GtkAccelKey *key,
return data == (gpointer) closure;
}
static const gchar *
gtk_accel_label_get_string (GtkAccelLabel *accel_label)
{
if (!accel_label->priv->accel_string)
gtk_accel_label_refetch (accel_label);
return accel_label->priv->accel_string;
}
/* Underscores in key names are better displayed as spaces
* E.g., Page_Up should be Page Up.
*
@@ -828,7 +876,7 @@ _gtk_accel_label_class_get_accelerator_label (GtkAccelLabelClass *klass,
}
ch = gdk_keyval_to_unicode (accelerator_key);
if (ch && (ch == ' ' || g_unichar_isgraph (ch)))
if (ch && ch < 0x80 && (g_unichar_isgraph (ch) || ch == ' '))
{
if (seen_mod)
g_string_append (gstring, klass->mod_separator);
@@ -887,10 +935,11 @@ gboolean
gtk_accel_label_refetch (GtkAccelLabel *accel_label)
{
gboolean enable_accels;
char *accel_string = NULL;
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), FALSE);
g_clear_pointer (&accel_label->priv->accel_string, g_free);
g_object_get (gtk_widget_get_settings (GTK_WIDGET (accel_label)),
"gtk-enable-accels", &enable_accels,
NULL);
@@ -930,20 +979,19 @@ gtk_accel_label_refetch (GtkAccelLabel *accel_label)
GtkAccelLabelClass *klass;
klass = GTK_ACCEL_LABEL_GET_CLASS (accel_label);
accel_string = _gtk_accel_label_class_get_accelerator_label (klass, accel_key, accel_mods);
accel_label->priv->accel_string =
_gtk_accel_label_class_get_accelerator_label (klass, accel_key, accel_mods);
}
else
/* Otherwise we have a closure with no key. Show "-/-". */
accel_string = g_strdup ("-/-");
accel_label->priv->accel_string = g_strdup ("-/-");
}
if (!accel_string)
accel_string = g_strdup ("");
if (!accel_label->priv->accel_string)
accel_label->priv->accel_string = g_strdup ("");
gtk_label_set_label (GTK_LABEL (accel_label->priv->accel_label), accel_string);
g_free (accel_string);
gtk_widget_queue_resize (GTK_WIDGET (accel_label));
return FALSE;
}
@@ -998,53 +1046,3 @@ gtk_accel_label_get_accel (GtkAccelLabel *accel_label,
*accelerator_key = accel_label->priv->accel_key;
*accelerator_mods = accel_label->priv->accel_mods;
}
void
gtk_accel_label_set_label (GtkAccelLabel *accel_label,
const char *text)
{
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
gtk_label_set_text_with_mnemonic (GTK_LABEL (priv->text_label), text);
}
const char *
gtk_accel_label_get_label (GtkAccelLabel *accel_label)
{
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), NULL);
return gtk_label_get_label (GTK_LABEL (priv->text_label));
}
void
gtk_accel_label_set_use_underline (GtkAccelLabel *accel_label,
gboolean setting)
{
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
setting = !!setting;
if (setting != gtk_label_get_use_underline (GTK_LABEL (priv->text_label)))
{
gtk_label_set_use_underline (GTK_LABEL (priv->text_label), setting);
g_object_notify_by_pspec (G_OBJECT (accel_label), props[PROP_USE_UNDERLINE]);
}
}
gboolean
gtk_accel_label_get_use_underline (GtkAccelLabel *accel_label)
{
GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label);
g_return_val_if_fail (GTK_IS_ACCEL_LABEL (accel_label), FALSE);
return gtk_label_get_use_underline (GTK_LABEL (priv->text_label));
}
+2 -17
View File
@@ -56,13 +56,13 @@ typedef struct _GtkAccelLabelPrivate GtkAccelLabelPrivate;
*/
struct _GtkAccelLabel
{
GtkWidget parent_instance;
GtkLabel label;
GtkAccelLabelPrivate *priv;
};
struct _GtkAccelLabelClass
{
GtkWidgetClass parent_class;
GtkLabelClass parent_class;
gchar *signal_quote1;
gchar *signal_quote2;
@@ -104,21 +104,6 @@ void gtk_accel_label_get_accel (GtkAccelLabel *accel_label,
guint *accelerator_key,
GdkModifierType *accelerator_mods);
GDK_AVAILABLE_IN_3_92
void gtk_accel_label_set_label (GtkAccelLabel *accel_label,
const char *text);
GDK_AVAILABLE_IN_3_92
const char * gtk_accel_label_get_label (GtkAccelLabel *accel_label);
GDK_AVAILABLE_IN_3_92
void gtk_accel_label_set_use_underline (GtkAccelLabel *accel_label,
gboolean setting);
GDK_AVAILABLE_IN_3_92
gboolean gtk_accel_label_get_use_underline (GtkAccelLabel *accel_label);
/* private */
gchar * _gtk_accel_label_class_get_accelerator_label (GtkAccelLabelClass *klass,
guint accelerator_key,
+83 -16
View File
@@ -26,6 +26,7 @@
#include "gtktypebuiltins.h"
#include "gtkbox.h"
#include "gtkrevealer.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkcontainerprivate.h"
#include "gtkprivate.h"
@@ -59,6 +60,8 @@ struct _GtkActionBarPrivate
GtkWidget *start_box;
GtkWidget *end_box;
GtkWidget *revealer;
GtkCssGadget *gadget;
};
enum {
@@ -68,7 +71,6 @@ enum {
};
enum {
PROP_0,
PROP_REVEALED,
LAST_PROP
};
@@ -131,6 +133,9 @@ gtk_action_bar_finalize (GObject *object)
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (object));
gtk_widget_unparent (priv->revealer);
g_clear_object (&priv->gadget);
G_OBJECT_CLASS (gtk_action_bar_parent_class)->finalize (object);
}
@@ -258,24 +263,78 @@ gtk_action_bar_set_child_property (GtkContainer *container,
}
}
static gboolean
gtk_action_bar_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkActionBar *self = GTK_ACTION_BAR (gtk_css_gadget_get_owner (gadget));
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (self));
gtk_widget_snapshot_child (GTK_WIDGET (self), priv->revealer, snapshot);
return FALSE;
}
static void
gtk_action_bar_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkActionBar *self = GTK_ACTION_BAR (widget);
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (self);
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
gtk_widget_snapshot_child (GTK_WIDGET (self), priv->revealer, snapshot);
gtk_css_gadget_snapshot (priv->gadget, snapshot);
}
static void
gtk_action_bar_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_action_bar_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
gtk_widget_size_allocate (priv->revealer, (GtkAllocation *)allocation);
gtk_widget_get_clip (priv->revealer, out_clip);
}
static void
gtk_action_bar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
gtk_widget_size_allocate (priv->revealer, allocation, baseline, out_clip);
GtkAllocation clip;
GTK_WIDGET_CLASS (gtk_action_bar_parent_class)->size_allocate (widget, allocation);
gtk_css_gadget_allocate (priv->gadget, allocation, gtk_widget_get_allocated_baseline (widget), &clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_action_bar_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer data)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
gtk_widget_measure (priv->revealer,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
@@ -289,11 +348,11 @@ gtk_action_bar_measure_ (GtkWidget *widget,
{
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
gtk_widget_measure (priv->revealer,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
gtk_css_gadget_get_preferred_size (priv->gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
@@ -399,8 +458,6 @@ gtk_action_bar_class_init (GtkActionBarClass *klass)
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, LAST_PROP, props);
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_PANEL);
gtk_widget_class_set_css_name (widget_class, "actionbar");
}
@@ -410,6 +467,7 @@ gtk_action_bar_init (GtkActionBar *action_bar)
{
GtkWidget *widget = GTK_WIDGET (action_bar);
GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (action_bar);
GtkCssNode *widget_node;
gtk_widget_set_has_window (widget, FALSE);
@@ -427,6 +485,15 @@ gtk_action_bar_init (GtkActionBar *action_bar)
gtk_center_box_set_end_widget (GTK_CENTER_BOX (priv->center_box), priv->end_box);
gtk_container_add (GTK_CONTAINER (priv->revealer), priv->center_box);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (action_bar));
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (action_bar),
gtk_action_bar_measure,
gtk_action_bar_allocate,
gtk_action_bar_render,
NULL,
NULL);
}
static void
+40 -45
View File
@@ -41,8 +41,7 @@ static void gtk_action_helper_action_added (GtkActi
GVariant *state,
gboolean should_emit_signals);
static void gtk_action_helper_action_removed (GtkActionHelper *helper,
gboolean should_emit_signals);
static void gtk_action_helper_action_removed (GtkActionHelper *helper);
static void gtk_action_helper_action_enabled_changed (GtkActionHelper *helper,
gboolean enabled);
@@ -191,8 +190,7 @@ gtk_action_helper_action_added (GtkActionHelper *helper,
}
static void
gtk_action_helper_action_removed (GtkActionHelper *helper,
gboolean should_emit_signals)
gtk_action_helper_action_removed (GtkActionHelper *helper)
{
GTK_NOTE(ACTIONS, g_message ("%s: action %s was removed", "actionhelper", helper->action_name));
@@ -204,17 +202,13 @@ gtk_action_helper_action_removed (GtkActionHelper *helper,
if (helper->enabled)
{
helper->enabled = FALSE;
if (should_emit_signals)
gtk_action_helper_report_change (helper, PROP_ENABLED);
gtk_action_helper_report_change (helper, PROP_ENABLED);
}
if (helper->active)
{
helper->active = FALSE;
if (should_emit_signals)
gtk_action_helper_report_change (helper, PROP_ACTIVE);
gtk_action_helper_report_change (helper, PROP_ACTIVE);
}
}
@@ -333,7 +327,7 @@ gtk_action_helper_observer_action_removed (GtkActionObserver *observer,
GtkActionObservable *observable,
const gchar *action_name)
{
gtk_action_helper_action_removed (GTK_ACTION_HELPER (observer), TRUE);
gtk_action_helper_action_removed (GTK_ACTION_HELPER (observer));
}
static void
@@ -387,17 +381,22 @@ GtkActionHelper *
gtk_action_helper_new (GtkActionable *widget)
{
GtkActionHelper *helper;
GParamSpec *pspec;
g_return_val_if_fail (GTK_IS_ACTIONABLE (widget), NULL);
helper = g_object_new (GTK_TYPE_ACTION_HELPER, NULL);
helper->widget = GTK_WIDGET (widget);
helper->enabled = gtk_widget_get_sensitive (GTK_WIDGET (helper->widget));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "active");
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
g_object_get (G_OBJECT (helper->widget), "active", &helper->active, NULL);
if (helper->widget)
{
GParamSpec *pspec;
helper->enabled = gtk_widget_get_sensitive (GTK_WIDGET (helper->widget));
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "active");
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
g_object_get (G_OBJECT (helper->widget), "active", &helper->active, NULL);
}
helper->action_context = _gtk_widget_get_action_muxer (GTK_WIDGET (widget), TRUE);
@@ -422,44 +421,40 @@ gtk_action_helper_set_action_name (GtkActionHelper *helper,
"it is unlikely to work",
"actionhelper", action_name));
if (helper->action_name)
{
gtk_action_observable_unregister_observer (GTK_ACTION_OBSERVABLE (helper->action_context),
helper->action_name,
GTK_ACTION_OBSERVER (helper));
g_free (helper->action_name);
}
helper->action_name = g_strdup (action_name);
gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (helper->action_context),
helper->action_name,
GTK_ACTION_OBSERVER (helper));
/* Start by recording the current state of our properties so we know
* what notify signals we will need to send.
*/
was_enabled = helper->enabled;
was_active = helper->active;
if (helper->action_name)
if (g_action_group_query_action (G_ACTION_GROUP (helper->action_context), helper->action_name,
&enabled, &parameter_type, NULL, NULL, &state))
{
gtk_action_helper_action_removed (helper, FALSE);
gtk_action_observable_unregister_observer (GTK_ACTION_OBSERVABLE (helper->action_context),
helper->action_name,
GTK_ACTION_OBSERVER (helper));
g_clear_pointer (&helper->action_name, g_free);
GTK_NOTE(ACTIONS, g_message ("%s: action %s existed from the start", "actionhelper", helper->action_name));
gtk_action_helper_action_added (helper, enabled, parameter_type, state, FALSE);
if (state)
g_variant_unref (state);
}
if (action_name)
else
{
helper->action_name = g_strdup (action_name);
gtk_action_observable_register_observer (GTK_ACTION_OBSERVABLE (helper->action_context),
helper->action_name,
GTK_ACTION_OBSERVER (helper));
if (g_action_group_query_action (G_ACTION_GROUP (helper->action_context), helper->action_name,
&enabled, &parameter_type, NULL, NULL, &state))
{
GTK_NOTE(ACTIONS, g_message ("%s: action %s existed from the start", "actionhelper", helper->action_name));
gtk_action_helper_action_added (helper, enabled, parameter_type, state, FALSE);
if (state)
g_variant_unref (state);
}
else
{
GTK_NOTE(ACTIONS, g_message ("%s: action %s missing from the start", "actionhelper", helper->action_name));
helper->enabled = FALSE;
}
GTK_NOTE(ACTIONS, g_message ("%s: action %s missing from the start", "actionhelper", helper->action_name));
helper->enabled = FALSE;
}
/* Send the notifies for the properties that changed.
+4 -6
View File
@@ -971,17 +971,15 @@ gtk_app_chooser_widget_snapshot (GtkWidget *widget,
}
static void
gtk_app_chooser_widget_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_app_chooser_widget_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkAppChooserWidget *self = GTK_APP_CHOOSER_WIDGET (widget);
GtkAppChooserWidgetPrivate *priv = gtk_app_chooser_widget_get_instance_private (self);
GTK_WIDGET_CLASS (gtk_app_chooser_widget_parent_class)->size_allocate (widget, allocation, baseline, out_clip);
GTK_WIDGET_CLASS (gtk_app_chooser_widget_parent_class)->size_allocate (widget, allocation);
gtk_widget_size_allocate (priv->overlay, allocation, baseline, out_clip);
gtk_widget_size_allocate (priv->overlay, allocation);
}
static void
-3
View File
@@ -131,9 +131,6 @@ gtk_application_get_proxy_if_service_present (GDBusConnection *connection,
NULL,
error);
if (!proxy)
return NULL;
/* is there anyone actually providing the service? */
owner = g_dbus_proxy_get_name_owner (proxy);
if (owner == NULL)
+1 -2
View File
@@ -860,8 +860,7 @@ gtk_application_get_window_by_id (GtkApplication *application,
* if another application has it this is just the most
* recently-focused window within this application.
*
* Returns: (transfer none) (nullable): the active window, or %NULL if
* there isn't one.
* Returns: (transfer none): the active window
*
* Since: 3.6
**/
+10 -10
View File
@@ -252,6 +252,8 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
{
gtk_widget_unparent (window->priv->menubar);
window->priv->menubar = NULL;
gtk_widget_queue_resize (GTK_WIDGET (window));
}
if (!have_menubar && should_have_menubar)
@@ -265,6 +267,8 @@ gtk_application_window_update_menubar (GtkApplicationWindow *window)
window->priv->menubar = gtk_menu_bar_new_from_model (G_MENU_MODEL (combined));
gtk_widget_set_parent (window->priv->menubar, GTK_WIDGET (window));
g_object_unref (combined);
gtk_widget_queue_resize (GTK_WIDGET (window));
}
}
@@ -590,10 +594,8 @@ gtk_application_window_measure (GtkWidget *widget,
}
static void
gtk_application_window_real_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_application_window_real_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
@@ -612,19 +614,17 @@ gtk_application_window_real_size_allocate (GtkWidget *widget,
&menubar_height, NULL, NULL, NULL);
menubar_allocation.height = menubar_height;
gtk_widget_size_allocate (window->priv->menubar, &menubar_allocation, baseline, out_clip);
gtk_widget_size_allocate (window->priv->menubar, &menubar_allocation);
child_allocation.y += menubar_height;
child_allocation.height -= menubar_height;
child = gtk_bin_get_child (GTK_BIN (window));
if (child != NULL && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child, &child_allocation, baseline, out_clip);
gtk_widget_size_allocate (child, &child_allocation);
}
else
GTK_WIDGET_CLASS (gtk_application_window_parent_class)->size_allocate (widget,
allocation,
baseline,
out_clip);
GTK_WIDGET_CLASS (gtk_application_window_parent_class)
->size_allocate (widget, allocation);
}
static void
+176 -59
View File
@@ -60,12 +60,14 @@
#include "gtksizerequest.h"
#include "gtkwidgetprivate.h"
#include "gtkcontainerprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkintl.h"
struct _GtkButtonBoxPrivate
{
GtkButtonBoxStyle layout_style;
GtkCssGadget *gadget;
};
enum {
@@ -90,17 +92,17 @@ static void gtk_button_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gtk_button_box_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline);
static void gtk_button_box_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
static void gtk_button_box_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static void gtk_button_box_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline);
static void gtk_button_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_button_box_remove (GtkContainer *container,
GtkWidget *widget);
static void gtk_button_box_set_child_property (GtkContainer *container,
@@ -114,6 +116,27 @@ static void gtk_button_box_get_child_property (GtkContainer *container,
GValue *value,
GParamSpec *pspec);
static void gtk_button_box_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer unused);
static void gtk_button_box_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer unused);
static gboolean gtk_button_box_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data);
#define DEFAULT_LAYOUT_STYLE GTK_BUTTONBOX_EDGE
G_DEFINE_TYPE_WITH_PRIVATE (GtkButtonBox, gtk_button_box, GTK_TYPE_BOX)
@@ -125,6 +148,16 @@ gtk_button_box_add (GtkContainer *container,
gtk_box_pack_start (GTK_BOX (container), widget);
}
static void
gtk_button_box_finalize (GObject *object)
{
GtkButtonBox *button_box = GTK_BUTTON_BOX (object);
g_clear_object (&button_box->priv->gadget);
G_OBJECT_CLASS (gtk_button_box_parent_class)->finalize (object);
}
static void
gtk_button_box_class_init (GtkButtonBoxClass *class)
{
@@ -138,9 +171,11 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
gobject_class->set_property = gtk_button_box_set_property;
gobject_class->get_property = gtk_button_box_get_property;
gobject_class->finalize = gtk_button_box_finalize;
widget_class->measure = gtk_button_box_measure;
widget_class->measure = gtk_button_box_measure_;
widget_class->size_allocate = gtk_button_box_size_allocate;
widget_class->snapshot= gtk_button_box_snapshot;
container_class->remove = gtk_button_box_remove;
container_class->add = gtk_button_box_add;
@@ -175,6 +210,47 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
gtk_widget_class_set_css_name (widget_class, "buttonbox");
}
static void
gtk_button_box_snapshot_forall (GtkWidget *child,
gpointer snapshot)
{
gtk_widget_snapshot_child (gtk_widget_get_parent (child),
child,
snapshot);
}
static gboolean
gtk_button_box_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer unused)
{
gtk_container_forall (GTK_CONTAINER (gtk_css_gadget_get_owner (gadget)),
gtk_button_box_snapshot_forall,
snapshot);
return FALSE;
}
static void
gtk_button_box_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
GtkCssGadget *gadget;
if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
gadget = gtk_box_get_gadget (GTK_BOX (widget));
else
gadget = priv->gadget;
gtk_css_gadget_snapshot (gadget, snapshot);
}
static void
gtk_button_box_init (GtkButtonBox *button_box)
{
@@ -182,6 +258,14 @@ gtk_button_box_init (GtkButtonBox *button_box)
button_box->priv->layout_style = DEFAULT_LAYOUT_STYLE;
gtk_box_set_spacing (GTK_BOX (button_box), 0);
button_box->priv->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (button_box)),
GTK_WIDGET (button_box),
gtk_button_box_measure,
gtk_button_box_allocate,
gtk_button_box_render,
NULL,
NULL);
}
static void
@@ -699,7 +783,41 @@ gtk_button_box_size_request (GtkWidget *widget,
}
static void
gtk_button_box_measure (GtkWidget *widget,
gtk_button_box_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer unused)
{
GtkWidget *widget;
GtkRequisition requisition;
int baseline;
int *pb;
if (minimum_baseline || natural_baseline)
pb = &baseline;
else
pb = NULL;
widget = gtk_css_gadget_get_owner (gadget);
gtk_button_box_size_request (widget, &requisition, pb);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = requisition.width;
else
*minimum = *natural = requisition.height;
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
}
static void
gtk_button_box_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
@@ -708,49 +826,53 @@ gtk_button_box_measure (GtkWidget *widget,
int *natural_baseline)
{
GtkButtonBoxPrivate *priv = gtk_button_box_get_instance_private (GTK_BUTTON_BOX (widget));
GtkCssGadget *gadget;
if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
{
GTK_WIDGET_CLASS (gtk_button_box_parent_class)->measure (widget, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
gadget = gtk_box_get_gadget (GTK_BOX (widget));
else
{
GtkRequisition requisition;
int baseline;
int *pb;
gadget = priv->gadget;
if (minimum_baseline || natural_baseline)
pb = &baseline;
else
pb = NULL;
gtk_button_box_size_request (widget, &requisition, pb);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = requisition.width;
else
*minimum = *natural = requisition.height;
if (orientation == GTK_ORIENTATION_VERTICAL)
{
if (minimum_baseline)
*minimum_baseline = baseline;
if (natural_baseline)
*natural_baseline = baseline;
}
}
gtk_css_gadget_get_preferred_size (gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_button_box_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_button_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkButtonBox *bbox = GTK_BUTTON_BOX (widget);
GtkButtonBoxPrivate *priv = bbox->priv;
GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
GtkCssGadget *gadget;
GdkRectangle clip;
if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
gadget = gtk_box_get_gadget (GTK_BOX (widget));
else
gadget = priv->gadget;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_button_box_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer unused)
{
GtkWidget *widget;
GtkButtonBoxPrivate *priv;
GtkButtonBox *bbox;
GList *children, *list;
GtkAllocation child_allocation;
gint nvis_children;
@@ -775,16 +897,10 @@ gtk_button_box_size_allocate (GtkWidget *widget,
gint baseline_height;
gint child_baseline;
gint i;
GdkRectangle child_clip;
if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
{
GTK_WIDGET_CLASS (gtk_button_box_parent_class)->size_allocate (widget,
allocation,
baseline,
out_clip);
return;
}
widget = gtk_css_gadget_get_owner (gadget);
bbox = GTK_BUTTON_BOX (widget);
priv = bbox->priv;
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (widget));
spacing = gtk_box_get_spacing (GTK_BOX (widget));
@@ -1034,8 +1150,7 @@ gtk_button_box_size_allocate (GtkWidget *widget,
}
}
gtk_widget_size_allocate (child, &child_allocation, child_baseline, &child_clip);
gdk_rectangle_union (out_clip, &child_clip, out_clip);
gtk_widget_size_allocate_with_baseline (child, &child_allocation, child_baseline);
i++;
}
}
@@ -1044,6 +1159,8 @@ gtk_button_box_size_allocate (GtkWidget *widget,
g_free (widths);
g_free (heights);
g_free (baselines);
gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
}
/**
+29 -25
View File
@@ -37,6 +37,8 @@
#include "config.h"
#include "gtkbin.h"
#include "gtksizerequest.h"
#include "gtkintl.h"
struct _GtkBinPrivate
@@ -60,22 +62,11 @@ static void gtk_bin_measure (GtkWidget
int *natural,
int *minimum_baseline,
int *natural_baseline);
static void gtk_bin_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkBin, gtk_bin, GTK_TYPE_CONTAINER)
static void
gtk_bin_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
GtkBin *bin = GTK_BIN (widget);
GtkBinPrivate *priv = gtk_bin_get_instance_private (bin);
if (priv->child && gtk_widget_get_visible (priv->child))
gtk_widget_size_allocate (priv->child, allocation, baseline, out_clip);
}
static void
gtk_bin_class_init (GtkBinClass *class)
{
@@ -94,13 +85,16 @@ gtk_bin_class_init (GtkBinClass *class)
static void
gtk_bin_init (GtkBin *bin)
{
bin->priv = gtk_bin_get_instance_private (bin);
gtk_widget_set_has_window (GTK_WIDGET (bin), FALSE);
}
static GType
gtk_bin_child_type (GtkContainer *container)
{
GtkBinPrivate *priv = gtk_bin_get_instance_private (GTK_BIN (container));
GtkBinPrivate *priv = GTK_BIN (container)->priv;
if (!priv->child)
return GTK_TYPE_WIDGET;
@@ -113,7 +107,7 @@ gtk_bin_add (GtkContainer *container,
GtkWidget *child)
{
GtkBin *bin = GTK_BIN (container);
GtkBinPrivate *priv = gtk_bin_get_instance_private (bin);
GtkBinPrivate *priv = bin->priv;
if (priv->child != NULL)
{
@@ -136,7 +130,7 @@ gtk_bin_remove (GtkContainer *container,
GtkWidget *child)
{
GtkBin *bin = GTK_BIN (container);
GtkBinPrivate *priv = gtk_bin_get_instance_private (bin);
GtkBinPrivate *priv = bin->priv;
gboolean widget_was_visible;
g_return_if_fail (priv->child == child);
@@ -159,7 +153,7 @@ gtk_bin_forall (GtkContainer *container,
gpointer callback_data)
{
GtkBin *bin = GTK_BIN (container);
GtkBinPrivate *priv = gtk_bin_get_instance_private (bin);
GtkBinPrivate *priv = bin->priv;
if (priv->child)
(* callback) (priv->child, callback_data);
@@ -191,6 +185,21 @@ gtk_bin_measure (GtkWidget *widget,
}
}
static void
gtk_bin_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkBin *bin = GTK_BIN (widget);
GtkBinPrivate *priv = bin->priv;
gtk_widget_set_allocation (widget, allocation);
if (priv->child && gtk_widget_get_visible (priv->child))
{
gtk_widget_size_allocate (priv->child, allocation);
}
}
/**
* gtk_bin_get_child:
* @bin: a #GtkBin
@@ -199,24 +208,19 @@ gtk_bin_measure (GtkWidget *widget,
* no child widget. The returned widget does not have a reference
* added, so you do not need to unref it.
*
* Returns: (transfer none) (nullable): the child of @bin, or %NULL if it does
* not have a child.
* Returns: (transfer none): pointer to child of the #GtkBin
**/
GtkWidget*
gtk_bin_get_child (GtkBin *bin)
{
GtkBinPrivate *priv = gtk_bin_get_instance_private (bin);
g_return_val_if_fail (GTK_IS_BIN (bin), NULL);
return priv->child;
return bin->priv->child;
}
void
_gtk_bin_set_child (GtkBin *bin,
GtkWidget *widget)
{
GtkBinPrivate *priv = gtk_bin_get_instance_private (bin);
priv->child = widget;
bin->priv->child = widget;
}
+3
View File
@@ -49,6 +49,9 @@ typedef struct _GtkBinClass GtkBinClass;
struct _GtkBin
{
GtkContainer container;
/*< private >*/
GtkBinPrivate *priv;
};
/**
+3 -7
View File
@@ -654,13 +654,9 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
else
handled = TRUE;
if (params != NULL)
{
for (i = 0; i < query.n_params + 1; i++)
g_value_unset (&params[i]);
g_free (params);
}
for (i = 0; i < query.n_params + 1; i++)
g_value_unset (&params[i]);
g_free (params);
if (entry->destroyed)
break;
+159 -42
View File
@@ -79,6 +79,7 @@
#include "gtkbox.h"
#include "gtkboxprivate.h"
#include "gtkcontainerprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcsspositionvalueprivate.h"
#include "gtkintl.h"
@@ -116,6 +117,7 @@ typedef struct _GtkBoxChild GtkBoxChild;
struct _GtkBoxPrivate
{
GList *children;
GtkCssGadget *gadget;
GtkOrientation orientation;
gint16 spacing;
@@ -142,9 +144,7 @@ struct _GtkBoxChild
};
static void gtk_box_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
GtkAllocation *allocation);
static void gtk_box_direction_changed (GtkWidget *widget,
GtkTextDirection previous_direction);
@@ -185,11 +185,24 @@ static void gtk_box_measure (GtkWidget *widget,
int *natural,
int *minimum_baseline,
int *natural_baseline);
static void gtk_box_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
G_DEFINE_TYPE_WITH_CODE (GtkBox, gtk_box, GTK_TYPE_CONTAINER,
G_ADD_PRIVATE (GtkBox)
G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
static void
gtk_box_dispose (GObject *object)
{
GtkBox *box = GTK_BOX (object);
GtkBoxPrivate *priv = box->priv;
g_clear_object (&priv->gadget);
G_OBJECT_CLASS (gtk_box_parent_class)->dispose (object);
}
static void
gtk_box_class_init (GtkBoxClass *class)
{
@@ -199,7 +212,9 @@ gtk_box_class_init (GtkBoxClass *class)
object_class->set_property = gtk_box_set_property;
object_class->get_property = gtk_box_get_property;
object_class->dispose = gtk_box_dispose;
widget_class->snapshot = gtk_box_snapshot;
widget_class->size_allocate = gtk_box_size_allocate;
widget_class->measure = gtk_box_measure;
widget_class->direction_changed = gtk_box_direction_changed;
@@ -328,27 +343,48 @@ gtk_box_get_property (GObject *object,
}
}
static gboolean
gtk_box_snapshot_contents (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data)
{
GTK_WIDGET_CLASS (gtk_box_parent_class)->snapshot (gtk_css_gadget_get_owner (gadget), snapshot);
return FALSE;
}
static void
gtk_box_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
gtk_css_gadget_snapshot (GTK_BOX (widget)->priv->gadget, snapshot);
}
static void
count_expand_children (GtkBox *box,
gint *visible_children,
gint *expand_children)
{
GtkBoxPrivate *private = box->priv;
GtkWidget *child;
GList *children;
GtkBoxChild *child;
*visible_children = *expand_children = 0;
for (child = _gtk_widget_get_first_child (GTK_WIDGET (box));
child != NULL;
child = _gtk_widget_get_next_sibling (child))
for (children = private->children; children; children = children->next)
{
if (_gtk_widget_get_visible (child))
{
*visible_children += 1;
child = children->data;
if (gtk_widget_compute_expand (child, private->orientation))
*expand_children += 1;
}
if (_gtk_widget_get_visible (child->widget))
{
*visible_children += 1;
if (gtk_widget_compute_expand (child->widget, private->orientation))
*expand_children += 1;
}
}
}
@@ -371,7 +407,6 @@ get_spacing (GtkBox *box)
static void
gtk_box_size_allocate_no_center (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GdkRectangle *out_clip)
{
GtkBox *box = GTK_BOX (widget);
@@ -388,6 +423,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
gint minimum_above, natural_above;
gint minimum_below, natural_below;
gboolean have_baseline;
gint baseline;
GtkPackType packing;
@@ -435,6 +471,24 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
/* Assert the api is working properly */
if (sizes[i].minimum_size < 0)
g_error ("GtkBox child %s minimum %s: %d < 0 for %s %d",
gtk_widget_get_name (GTK_WIDGET (child->widget)),
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height",
sizes[i].minimum_size,
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width",
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width);
if (sizes[i].natural_size < sizes[i].minimum_size)
g_error ("GtkBox child %s natural %s: %d < minimum %d for %s %d",
gtk_widget_get_name (GTK_WIDGET (child->widget)),
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height",
sizes[i].natural_size,
sizes[i].minimum_size,
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width",
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width);
children_minimum_size += sizes[i].minimum_size;
sizes[i].data = child;
@@ -524,7 +578,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
sizes[i].natural_size = child_size;
if (private->orientation == GTK_ORIENTATION_HORIZONTAL &&
gtk_widget_get_valign (child->widget) == GTK_ALIGN_BASELINE)
gtk_widget_get_valign (child->widget) == GTK_ALIGN_BASELINE)
{
int child_allocation_width;
int child_minimum_height, child_natural_height;
@@ -552,11 +606,7 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
}
}
if (private->orientation == GTK_ORIENTATION_VERTICAL)
baseline = -1;
/* we only calculate our own baseline if we don't get one passed from the parent
* and any of the child widgets explicitly request one */
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline == -1 && have_baseline)
{
gint height = MAX (1, allocation->height);
@@ -658,7 +708,8 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
child_allocation.y -= child_size;
}
}
gtk_widget_size_allocate (child->widget, &child_allocation, baseline, &clip);
gtk_widget_size_allocate_with_baseline (child->widget, &child_allocation, baseline);
gtk_widget_get_clip (child->widget, &clip);
gdk_rectangle_union (&clip, out_clip, out_clip);
i++;
@@ -667,12 +718,33 @@ gtk_box_size_allocate_no_center (GtkWidget *widget,
}
static void
gtk_box_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_box_allocate_contents (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer unused)
{
gtk_box_size_allocate_no_center (widget, allocation, baseline, out_clip);
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
*out_clip = *allocation;
gtk_box_size_allocate_no_center (widget, allocation, out_clip);
}
static void
gtk_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkBoxPrivate *priv = GTK_BOX (widget)->priv;
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static GType
@@ -1053,6 +1125,22 @@ gtk_box_get_size (GtkWidget *widget,
*natural_baseline = nat_baseline;
}
static void
gtk_box_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
gint avail_size,
@@ -1102,6 +1190,20 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
/* Assert the api is working properly */
if (sizes[i].minimum_size < 0)
g_error ("GtkBox child %s minimum %s: %d < 0",
gtk_widget_get_name (GTK_WIDGET (child->widget)),
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height",
sizes[i].minimum_size);
if (sizes[i].natural_size < sizes[i].minimum_size)
g_error ("GtkBox child %s natural %s: %d < minimum %d",
gtk_widget_get_name (GTK_WIDGET (child->widget)),
(private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height",
sizes[i].natural_size,
sizes[i].minimum_size);
children_minimum_size += sizes[i].minimum_size;
sizes[i].data = child;
@@ -1312,16 +1414,17 @@ gtk_box_compute_size_for_orientation (GtkBox *box,
*natural_size = required_natural;
}
static void
gtk_box_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
gtk_box_get_content_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline,
gpointer unused)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkBox *box = GTK_BOX (widget);
GtkBoxPrivate *private = box->priv;
@@ -1330,15 +1433,15 @@ gtk_box_measure (GtkWidget *widget,
else
{
if (private->orientation != orientation)
gtk_box_compute_size_for_opposing_orientation (box, for_size, minimum, natural, minimum_baseline, natural_baseline);
gtk_box_compute_size_for_opposing_orientation (box, for_size, minimum, natural, minimum_baseline, natural_baseline);
else
{
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
gtk_box_compute_size_for_orientation (box, for_size, minimum, natural);
}
{
if (minimum_baseline)
*minimum_baseline = -1;
if (natural_baseline)
*natural_baseline = -1;
gtk_box_compute_size_for_orientation (box, for_size, minimum, natural);
}
}
}
@@ -1360,9 +1463,23 @@ gtk_box_init (GtkBox *box)
private->spacing = 0;
private->baseline_pos = GTK_BASELINE_POSITION_CENTER;
private->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (box)),
GTK_WIDGET (box),
gtk_box_get_content_size,
gtk_box_allocate_contents,
gtk_box_snapshot_contents,
NULL,
NULL);
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (box));
}
GtkCssGadget *
gtk_box_get_gadget (GtkBox *box)
{
return box->priv->gadget;
}
/**
* gtk_box_new:
* @orientation: the boxs orientation.
+866
View File
@@ -0,0 +1,866 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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>
*/
#include "config.h"
#include "gtkboxgadgetprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcsspositionvalueprivate.h"
#include "gtkmain.h"
#include "gtkprivate.h"
#include "gtksizerequest.h"
#include "gtkwidgetprivate.h"
#include "gtkcontainerprivate.h"
/* GtkBoxGadget is a container gadget implementation that arranges its
* children in a row, either horizontally or vertically. Children can
* be either widgets or gadgets, and can be set to expand horizontally
* or vertically, or both.
*/
typedef struct _GtkBoxGadgetPrivate GtkBoxGadgetPrivate;
struct _GtkBoxGadgetPrivate {
GtkOrientation orientation;
GArray *children;
guint draw_focus : 1;
guint draw_reverse : 1;
guint allocate_reverse : 1;
guint align_reverse : 1;
};
typedef gboolean (* ComputeExpandFunc) (GObject *object, GtkOrientation orientation);
typedef struct _GtkBoxGadgetChild GtkBoxGadgetChild;
struct _GtkBoxGadgetChild {
GObject *object;
gboolean expand;
GtkAlign align;
};
G_DEFINE_TYPE_WITH_CODE (GtkBoxGadget, gtk_box_gadget, GTK_TYPE_CSS_GADGET,
G_ADD_PRIVATE (GtkBoxGadget))
static gboolean
gtk_box_gadget_child_is_visible (GObject *child)
{
if (GTK_IS_WIDGET (child))
return gtk_widget_get_visible (GTK_WIDGET (child));
else
return gtk_css_gadget_get_visible (GTK_CSS_GADGET (child));
}
static gboolean
gtk_box_gadget_child_compute_expand (GtkBoxGadget *gadget,
GtkBoxGadgetChild *child)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
if (child->expand)
return TRUE;
if (GTK_IS_WIDGET (child->object))
return gtk_widget_compute_expand (GTK_WIDGET (child->object), priv->orientation);
return FALSE;
}
static GtkAlign
gtk_box_gadget_child_get_align (GtkBoxGadget *gadget,
GtkBoxGadgetChild *child)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
GtkAlign align;
if (GTK_IS_WIDGET (child->object))
{
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
g_object_get (child->object, "valign", &align, NULL);
else
g_object_get (child->object, "halign", &align, NULL);
}
else
align = child->align;
return align;
}
static GtkAlign
effective_align (GtkAlign align,
gboolean reverse)
{
switch (align)
{
case GTK_ALIGN_START:
return reverse ? GTK_ALIGN_END : GTK_ALIGN_START;
case GTK_ALIGN_END:
return reverse ? GTK_ALIGN_START : GTK_ALIGN_END;
default:
return align;
}
}
static int
get_spacing (GtkCssGadget *gadget)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
GtkCssValue *spacing = gtk_css_style_get_value (gtk_css_gadget_get_style (gadget), GTK_CSS_PROPERTY_BORDER_SPACING);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
return _gtk_css_position_value_get_x (spacing, 100);
else
return _gtk_css_position_value_get_y (spacing, 100);
}
static void
gtk_box_gadget_measure_child (GObject *child,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
if (GTK_IS_WIDGET (child))
{
gtk_widget_measure (GTK_WIDGET (child),
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
else
{
gtk_css_gadget_get_preferred_size (GTK_CSS_GADGET (child),
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
}
static void
gtk_box_gadget_distribute (GtkBoxGadget *gadget,
gint for_size,
gint size,
GtkRequestedSize *sizes)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
guint i, n_expand;
gint spacing;
n_expand = 0;
spacing = get_spacing (GTK_CSS_GADGET (gadget));
size += spacing;
for (i = 0 ; i < priv->children->len; i++)
{
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, i);
gtk_box_gadget_measure_child (child->object,
priv->orientation,
for_size,
&sizes[i].minimum_size, &sizes[i].natural_size,
NULL, NULL);
if (gtk_box_gadget_child_is_visible (child->object))
{
size -= spacing;
if (gtk_box_gadget_child_compute_expand (gadget, child))
n_expand++;
}
size -= sizes[i].minimum_size;
}
if G_UNLIKELY (size < 0)
{
g_critical ("%s: assertion 'size >= 0' failed in %s", G_STRFUNC, G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (GTK_CSS_GADGET (gadget))));
return;
}
size = gtk_distribute_natural_allocation (size, priv->children->len, sizes);
if (size <= 0 || n_expand == 0)
return;
for (i = 0 ; i < priv->children->len; i++)
{
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, i);
if (!gtk_box_gadget_child_is_visible (child->object) ||
!gtk_box_gadget_child_compute_expand (gadget, child))
continue;
sizes[i].minimum_size += size / n_expand;
/* distribute all pixels, even if there's a remainder */
size -= size / n_expand;
n_expand--;
}
}
static void
gtk_box_gadget_measure_orientation (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
gint child_min, child_nat, spacing;
guint i, n_visible;
*minimum = 0;
*natural = 0;
spacing = get_spacing (gadget);
n_visible = 0;
for (i = 0 ; i < priv->children->len; i++)
{
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, i);
gtk_box_gadget_measure_child (child->object,
orientation,
for_size,
&child_min, &child_nat,
NULL, NULL);
*minimum += child_min;
*natural += child_nat;
if (gtk_box_gadget_child_is_visible (child->object))
n_visible++;
}
*minimum += (MAX (n_visible, 1) - 1) * spacing;
*natural += (MAX (n_visible, 1) - 1) * spacing;
}
static void
gtk_box_gadget_measure_opposite (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
int child_min, child_nat, child_min_baseline, child_nat_baseline;
int total_min, above_min, below_min, total_nat, above_nat, below_nat;
GtkRequestedSize *sizes;
guint i;
if (for_size >= 0)
{
sizes = g_newa (GtkRequestedSize, priv->children->len);
gtk_box_gadget_distribute (GTK_BOX_GADGET (gadget), -1, for_size, sizes);
}
above_min = below_min = above_nat = below_nat = -1;
total_min = total_nat = 0;
for (i = 0 ; i < priv->children->len; i++)
{
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, i);
gtk_box_gadget_measure_child (child->object,
orientation,
for_size >= 0 ? sizes[i].minimum_size : -1,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
if (child_min_baseline >= 0)
{
below_min = MAX (below_min, child_min - child_min_baseline);
above_min = MAX (above_min, child_min_baseline);
below_nat = MAX (below_nat, child_nat - child_nat_baseline);
above_nat = MAX (above_nat, child_nat_baseline);
}
else
{
total_min = MAX (total_min, child_min);
total_nat = MAX (total_nat, child_nat);
}
}
if (above_min >= 0)
{
total_min = MAX (total_min, above_min + below_min);
total_nat = MAX (total_nat, above_nat + below_nat);
/* assume GTK_BASELINE_POSITION_CENTER for now */
if (minimum_baseline)
*minimum_baseline = above_min + (total_min - (above_min + below_min)) / 2;
if (natural_baseline)
*natural_baseline = above_nat + (total_nat - (above_nat + below_nat)) / 2;
}
*minimum = total_min;
*natural = total_nat;
}
static void
gtk_box_gadget_get_preferred_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
if (priv->orientation == orientation)
gtk_box_gadget_measure_orientation (gadget, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline);
else
gtk_box_gadget_measure_opposite (gadget, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline);
}
static void
gtk_box_gadget_allocate_child (GObject *child,
GtkOrientation box_orientation,
GtkAlign child_align,
GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
if (GTK_IS_WIDGET (child))
{
gtk_widget_size_allocate_with_baseline (GTK_WIDGET (child), allocation, baseline);
gtk_widget_get_clip (GTK_WIDGET (child), out_clip);
}
else
{
GtkAllocation child_allocation;
int minimum, natural;
int minimum_baseline, natural_baseline;
if (box_orientation == GTK_ORIENTATION_HORIZONTAL)
{
child_allocation.width = allocation->width;
child_allocation.x = allocation->x;
gtk_css_gadget_get_preferred_size (GTK_CSS_GADGET (child),
GTK_ORIENTATION_VERTICAL,
allocation->width,
&minimum, &natural,
&minimum_baseline, &natural_baseline);
switch (child_align)
{
case GTK_ALIGN_FILL:
child_allocation.height = allocation->height;
child_allocation.y = allocation->y;
break;
case GTK_ALIGN_START:
child_allocation.height = MIN(natural, allocation->height);
child_allocation.y = allocation->y;
break;
case GTK_ALIGN_END:
child_allocation.height = MIN(natural, allocation->height);
child_allocation.y = allocation->y + allocation->height - child_allocation.height;
break;
case GTK_ALIGN_BASELINE:
if (minimum_baseline >= 0 && baseline >= 0)
{
child_allocation.height = MIN(natural, allocation->height);
child_allocation.y = allocation->y + MAX(0, baseline - minimum_baseline);
break;
}
case GTK_ALIGN_CENTER:
child_allocation.height = MIN(natural, allocation->height);
child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
break;
default:
g_assert_not_reached ();
}
}
else
{
child_allocation.height = allocation->height;
child_allocation.y = allocation->y;
gtk_css_gadget_get_preferred_size (GTK_CSS_GADGET (child),
GTK_ORIENTATION_HORIZONTAL,
allocation->height,
&minimum, &natural,
NULL, NULL);
switch (child_align)
{
case GTK_ALIGN_FILL:
child_allocation.width = allocation->width;
child_allocation.x = allocation->x;
break;
case GTK_ALIGN_START:
child_allocation.width = MIN(natural, allocation->width);
child_allocation.x = allocation->x;
break;
case GTK_ALIGN_END:
child_allocation.width = MIN(natural, allocation->width);
child_allocation.x = allocation->x + allocation->width - child_allocation.width;
break;
case GTK_ALIGN_BASELINE:
case GTK_ALIGN_CENTER:
child_allocation.width = MIN(natural, allocation->width);
child_allocation.x = allocation->x + (allocation->width - child_allocation.width) / 2;
break;
default:
g_assert_not_reached ();
}
}
gtk_css_gadget_allocate (GTK_CSS_GADGET (child), &child_allocation, baseline, out_clip);
}
}
static void
gtk_box_gadget_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
GtkRequestedSize *sizes;
GtkAllocation child_allocation, child_clip;
GtkAlign child_align;
gint spacing;
guint i;
child_allocation = *allocation;
sizes = g_newa (GtkRequestedSize, priv->children->len);
spacing = get_spacing (gadget);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
gtk_box_gadget_distribute (GTK_BOX_GADGET (gadget), allocation->height, allocation->width, sizes);
if (priv->allocate_reverse)
child_allocation.x = allocation->x + allocation->width;
for (i = 0; i < priv->children->len; i++)
{
guint idx = priv->allocate_reverse ? priv->children->len - 1 - i : i;
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, idx);
child_allocation.width = sizes[idx].minimum_size;
child_allocation.height = allocation->height;
child_allocation.y = allocation->y;
if (priv->allocate_reverse)
child_allocation.x -= child_allocation.width + spacing;
child_align = gtk_box_gadget_child_get_align (GTK_BOX_GADGET (gadget), child);
gtk_box_gadget_allocate_child (child->object,
priv->orientation,
effective_align (child_align, priv->align_reverse),
&child_allocation,
baseline,
&child_clip);
if (i == 0)
*out_clip = child_clip;
else
gdk_rectangle_union (out_clip, &child_clip, out_clip);
if (!priv->allocate_reverse)
child_allocation.x += sizes[idx].minimum_size + spacing;
}
}
else
{
gtk_box_gadget_distribute (GTK_BOX_GADGET (gadget), allocation->width, allocation->height, sizes);
if (priv->allocate_reverse)
child_allocation.y = allocation->y + allocation->height;
for (i = 0 ; i < priv->children->len; i++)
{
guint idx = priv->allocate_reverse ? priv->children->len - 1 - i : i;
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, idx);
child_allocation.height = sizes[idx].minimum_size;
child_allocation.width = allocation->width;
child_allocation.x = allocation->x;
if (priv->allocate_reverse)
child_allocation.y -= child_allocation.height + spacing;
child_align = gtk_box_gadget_child_get_align (GTK_BOX_GADGET (gadget), child);
gtk_box_gadget_allocate_child (child->object,
priv->orientation,
effective_align (child_align, priv->align_reverse),
&child_allocation,
-1,
&child_clip);
if (i == 0)
*out_clip = child_clip;
else
gdk_rectangle_union (out_clip, &child_clip, out_clip);
if (!priv->allocate_reverse)
child_allocation.y += sizes[idx].minimum_size + spacing;
}
}
}
static gboolean
gtk_box_gadget_snapshot (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
GtkWidget *owner = gtk_css_gadget_get_owner (gadget);
guint i;
for (i = 0; i < priv->children->len; i++)
{
guint draw_index = priv->draw_reverse ? priv->children->len - 1 - i : i;
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, draw_index);
if (GTK_IS_WIDGET (child->object))
gtk_widget_snapshot_child (owner, GTK_WIDGET (child->object), snapshot);
else
gtk_css_gadget_snapshot (GTK_CSS_GADGET (child->object), snapshot);
}
if (priv->draw_focus && gtk_widget_has_visible_focus (owner))
return TRUE;
return FALSE;
}
static void
gtk_box_gadget_finalize (GObject *object)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (object));
g_array_free (priv->children, TRUE);
G_OBJECT_CLASS (gtk_box_gadget_parent_class)->finalize (object);
}
static void
gtk_box_gadget_class_init (GtkBoxGadgetClass *klass)
{
GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_box_gadget_finalize;
gadget_class->get_preferred_size = gtk_box_gadget_get_preferred_size;
gadget_class->allocate = gtk_box_gadget_allocate;
gadget_class->snapshot = gtk_box_gadget_snapshot;
}
static void
gtk_box_gadget_clear_child (gpointer data)
{
GtkBoxGadgetChild *child = data;
g_object_unref (child->object);
}
static void
gtk_box_gadget_init (GtkBoxGadget *gadget)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
priv->children = g_array_new (FALSE, FALSE, sizeof (GtkBoxGadgetChild));
g_array_set_clear_func (priv->children, gtk_box_gadget_clear_child);
}
GtkCssGadget *
gtk_box_gadget_new_for_node (GtkCssNode *node,
GtkWidget *owner)
{
return g_object_new (GTK_TYPE_BOX_GADGET,
"node", node,
"owner", owner,
NULL);
}
GtkCssGadget *
gtk_box_gadget_new (const char *name,
GtkWidget *owner,
GtkCssGadget *parent,
GtkCssGadget *next_sibling)
{
GtkCssNode *node;
GtkCssGadget *result;
node = gtk_css_node_new ();
gtk_css_node_set_name (node, g_intern_string (name));
if (parent)
gtk_css_node_insert_before (gtk_css_gadget_get_node (parent),
node,
next_sibling ? gtk_css_gadget_get_node (next_sibling) : NULL);
result = gtk_box_gadget_new_for_node (node, owner);
g_object_unref (node);
return result;
}
void
gtk_box_gadget_set_orientation (GtkBoxGadget *gadget,
GtkOrientation orientation)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
priv->orientation = orientation;
}
void
gtk_box_gadget_set_draw_focus (GtkBoxGadget *gadget,
gboolean draw_focus)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
priv->draw_focus = draw_focus;
}
void
gtk_box_gadget_set_draw_reverse (GtkBoxGadget *gadget,
gboolean draw_reverse)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
priv->draw_reverse = draw_reverse;
}
void
gtk_box_gadget_set_allocate_reverse (GtkBoxGadget *gadget,
gboolean allocate_reverse)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
priv->allocate_reverse = allocate_reverse;
}
void
gtk_box_gadget_set_align_reverse (GtkBoxGadget *gadget,
gboolean align_reverse)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
priv->align_reverse = align_reverse;
}
static GtkCssNode *
get_css_node (GObject *child)
{
if (GTK_IS_WIDGET (child))
return gtk_widget_get_css_node (GTK_WIDGET (child));
else
return gtk_css_gadget_get_node (GTK_CSS_GADGET (child));
}
static void
gtk_box_gadget_insert_object (GtkBoxGadget *gadget,
int pos,
GObject *object,
gboolean expand,
GtkAlign align)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
GtkBoxGadgetChild child;
child.object = g_object_ref (object);
child.expand = expand;
child.align = align;
if (pos < 0 || pos >= priv->children->len)
{
g_array_append_val (priv->children, child);
gtk_css_node_insert_before (gtk_css_gadget_get_node (GTK_CSS_GADGET (gadget)),
get_css_node (object),
NULL);
}
else
{
g_array_insert_val (priv->children, pos, child);
gtk_css_node_insert_before (gtk_css_gadget_get_node (GTK_CSS_GADGET (gadget)),
get_css_node (object),
get_css_node (g_array_index (priv->children, GtkBoxGadgetChild, pos + 1).object));
}
}
void
gtk_box_gadget_insert_widget (GtkBoxGadget *gadget,
int pos,
GtkWidget *widget)
{
gtk_box_gadget_insert_object (gadget, pos, G_OBJECT (widget), FALSE, GTK_ALIGN_FILL);
}
static GtkBoxGadgetChild *
gtk_box_gadget_find_object (GtkBoxGadget *gadget,
GObject *object,
int *position)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
guint i;
for (i = 0; i < priv->children->len; i++)
{
GtkBoxGadgetChild *child = &g_array_index (priv->children, GtkBoxGadgetChild, i);
if (child->object == object)
{
if (position)
*position = i;
return child;
}
}
return NULL;
}
static void
gtk_box_gadget_remove_object (GtkBoxGadget *gadget,
GObject *object)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (gadget);
GtkBoxGadgetChild *child;
int position;
child = gtk_box_gadget_find_object (gadget, object, &position);
if (child)
{
gtk_css_node_set_parent (get_css_node (child->object), NULL);
g_array_remove_index (priv->children, position);
}
}
void
gtk_box_gadget_remove_widget (GtkBoxGadget *gadget,
GtkWidget *widget)
{
gtk_box_gadget_remove_object (gadget, G_OBJECT (widget));
}
void
gtk_box_gadget_insert_gadget_before (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean expand,
GtkAlign align)
{
/* Insert at the end if no sibling specified */
int pos = -1;
if (sibling)
gtk_box_gadget_find_object (gadget, G_OBJECT (sibling), &pos);
gtk_box_gadget_insert_gadget (gadget, pos, cssgadget, expand, align);
}
void
gtk_box_gadget_insert_gadget_after (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean expand,
GtkAlign align)
{
/* Insert at the beginning if no sibling specified */
int pos = 0;
if (sibling && gtk_box_gadget_find_object (gadget, G_OBJECT (sibling), &pos))
pos++;
gtk_box_gadget_insert_gadget (gadget, pos, cssgadget, expand, align);
}
void
gtk_box_gadget_insert_gadget (GtkBoxGadget *gadget,
int pos,
GtkCssGadget *cssgadget,
gboolean expand,
GtkAlign align)
{
gtk_box_gadget_insert_object (gadget, pos, G_OBJECT (cssgadget), expand, align);
}
void
gtk_box_gadget_remove_gadget (GtkBoxGadget *gadget,
GtkCssGadget *cssgadget)
{
gtk_box_gadget_remove_object (gadget, G_OBJECT (cssgadget));
}
void
gtk_box_gadget_reverse_children (GtkBoxGadget *gadget)
{
GtkBoxGadgetPrivate *priv = gtk_box_gadget_get_instance_private (GTK_BOX_GADGET (gadget));
int i, j;
gtk_css_node_reverse_children (gtk_css_gadget_get_node (GTK_CSS_GADGET (gadget)));
for (i = 0, j = priv->children->len - 1; i < j; i++, j--)
{
GtkBoxGadgetChild *child1 = &g_array_index (priv->children, GtkBoxGadgetChild, i);
GtkBoxGadgetChild *child2 = &g_array_index (priv->children, GtkBoxGadgetChild, j);
GtkBoxGadgetChild tmp;
tmp = *child1;
*child1 = *child2;
*child2 = tmp;
}
}
void
gtk_box_gadget_set_gadget_expand (GtkBoxGadget *gadget,
GObject *object,
gboolean expand)
{
GtkBoxGadgetChild *child;
child = gtk_box_gadget_find_object (gadget, object, NULL);
if (!child)
return;
if (child->expand == expand)
return;
child->expand = expand;
gtk_css_gadget_queue_resize (GTK_CSS_GADGET (gadget));
}
void
gtk_box_gadget_set_gadget_align (GtkBoxGadget *gadget,
GObject *object,
GtkAlign align)
{
GtkBoxGadgetChild *child;
child = gtk_box_gadget_find_object (gadget, object, NULL);
if (!child)
return;
if (child->align == align)
return;
child->align = align;
gtk_css_gadget_queue_resize (GTK_CSS_GADGET (gadget));
}
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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_BOX_GADGET_PRIVATE_H__
#define __GTK_BOX_GADGET_PRIVATE_H__
#include "gtk/gtkcssgadgetprivate.h"
#include "gtk/gtkenums.h"
G_BEGIN_DECLS
#define GTK_TYPE_BOX_GADGET (gtk_box_gadget_get_type ())
#define GTK_BOX_GADGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_BOX_GADGET, GtkBoxGadget))
#define GTK_BOX_GADGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_BOX_GADGET, GtkBoxGadgetClass))
#define GTK_IS_BOX_GADGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_BOX_GADGET))
#define GTK_IS_BOX_GADGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_BOX_GADGET))
#define GTK_BOX_GADGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_BOX_GADGET, GtkBoxGadgetClass))
typedef struct _GtkBoxGadget GtkBoxGadget;
typedef struct _GtkBoxGadgetClass GtkBoxGadgetClass;
struct _GtkBoxGadget
{
GtkCssGadget parent;
};
struct _GtkBoxGadgetClass
{
GtkCssGadgetClass parent_class;
};
GType gtk_box_gadget_get_type (void) G_GNUC_CONST;
GtkCssGadget * gtk_box_gadget_new (const char *name,
GtkWidget *owner,
GtkCssGadget *parent,
GtkCssGadget *next_sibling);
GtkCssGadget * gtk_box_gadget_new_for_node (GtkCssNode *node,
GtkWidget *owner);
void gtk_box_gadget_set_orientation (GtkBoxGadget *gadget,
GtkOrientation orientation);
void gtk_box_gadget_set_draw_focus (GtkBoxGadget *gadget,
gboolean draw_focus);
void gtk_box_gadget_set_draw_reverse (GtkBoxGadget *gadget,
gboolean draw_reverse);
void gtk_box_gadget_set_allocate_reverse (GtkBoxGadget *gadget,
gboolean allocate_reverse);
void gtk_box_gadget_set_align_reverse (GtkBoxGadget *gadget,
gboolean align_reverse);
void gtk_box_gadget_insert_widget (GtkBoxGadget *gadget,
int pos,
GtkWidget *widget);
void gtk_box_gadget_remove_widget (GtkBoxGadget *gadget,
GtkWidget *widget);
void gtk_box_gadget_insert_gadget (GtkBoxGadget *gadget,
int pos,
GtkCssGadget *cssgadget,
gboolean expand,
GtkAlign align);
void gtk_box_gadget_insert_gadget_before (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean expand,
GtkAlign align);
void gtk_box_gadget_insert_gadget_after (GtkBoxGadget *gadget,
GtkCssGadget *sibling,
GtkCssGadget *cssgadget,
gboolean expand,
GtkAlign align);
void gtk_box_gadget_remove_gadget (GtkBoxGadget *gadget,
GtkCssGadget *cssgadget);
void gtk_box_gadget_reverse_children (GtkBoxGadget *gadget);
void gtk_box_gadget_set_gadget_expand (GtkBoxGadget *gadget,
GObject *object,
gboolean expand);
void gtk_box_gadget_set_gadget_align (GtkBoxGadget *gadget,
GObject *object,
GtkAlign align);
G_END_DECLS
#endif /* __GTK_BOX_GADGET_PRIVATE_H__ */
+5
View File
@@ -20,11 +20,16 @@
#define __GTK_BOX_PRIVATE_H__
#include "gtkbox.h"
#include "gtkcssgadgetprivate.h"
G_BEGIN_DECLS
GList *_gtk_box_get_children (GtkBox *box);
GtkCssGadget *gtk_box_get_gadget (GtkBox *box);
G_END_DECLS
#endif /* __GTK_BOX_PRIVATE_H__ */
+4
View File
@@ -62,6 +62,10 @@
* specified in an XML format which can be roughly described by the
* RELAX NG schema below. We refer to these descriptions as GtkBuilder
* UI definitions or just UI definitions if the context is clear.
* Do not confuse GtkBuilder UI Definitions with
* [GtkUIManager UI Definitions][XML-UI], which are more limited in scope.
* It is common to use `.ui` as the filename extension for files containing
* GtkBuilder UI definitions.
*
* [RELAX NG Compact Syntax](https://git.gnome.org/browse/gtk+/tree/gtk/gtkbuilder.rnc)
*
+267
View File
@@ -0,0 +1,267 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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>
*/
#include "config.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkrendericonprivate.h"
#include "gtksnapshot.h"
/* GtkBuiltinIcon is a gadget implementation that is meant to replace
* all calls to gtk_render_ functions to render arrows, expanders, checks
* radios, handles, separators, etc. See the GtkCssImageBuiltinType
* enumeration for the full set of builtin icons that this gadget can
* render.
*
* Use gtk_builtin_icon_set_image to set which of the builtin icons
* is rendered.
*
* Use gtk_builtin_icon_set_default_size to set a non-zero default
* size for the icon.
*
* Themes can override the acutal image that is used with the
* -gtk-icon-source property. If it is not specified, a builtin
* fallback is used.
*/
typedef struct _GtkBuiltinIconPrivate GtkBuiltinIconPrivate;
struct _GtkBuiltinIconPrivate {
GtkCssImageBuiltinType image_type;
int default_size;
int strikethrough;
gboolean strikethrough_valid;
};
G_DEFINE_TYPE_WITH_CODE (GtkBuiltinIcon, gtk_builtin_icon, GTK_TYPE_CSS_GADGET,
G_ADD_PRIVATE (GtkBuiltinIcon))
static void
gtk_builtin_icon_get_preferred_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget));
double min_size;
guint property;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
property = GTK_CSS_PROPERTY_MIN_WIDTH;
else
property = GTK_CSS_PROPERTY_MIN_HEIGHT;
min_size = _gtk_css_number_value_get (gtk_css_style_get_value (gtk_css_gadget_get_style (gadget), property), 100);
if (min_size > 0.0)
{
*minimum = *natural = min_size;
}
else
{
*minimum = *natural = priv->default_size;
}
if (minimum_baseline)
{
if (!priv->strikethrough_valid)
{
GtkWidget *widget;
PangoContext *pango_context;
const PangoFontDescription *font_desc;
PangoFontMetrics *metrics;
widget = gtk_css_gadget_get_owner (gadget);
pango_context = gtk_widget_get_pango_context (widget);
font_desc = pango_context_get_font_description (pango_context);
metrics = pango_context_get_metrics (pango_context,
font_desc,
pango_context_get_language (pango_context));
priv->strikethrough = pango_font_metrics_get_strikethrough_position (metrics);
priv->strikethrough_valid = TRUE;
pango_font_metrics_unref (metrics);
}
*minimum_baseline = *minimum * 0.5 + PANGO_PIXELS (priv->strikethrough);
}
if (natural_baseline)
*natural_baseline = *minimum_baseline;
}
static void
gtk_builtin_icon_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
GdkRectangle icon_clip;
GTK_CSS_GADGET_CLASS (gtk_builtin_icon_parent_class)->allocate (gadget, allocation, baseline, out_clip);
gtk_css_style_render_icon_get_extents (gtk_css_gadget_get_style (gadget),
&icon_clip,
allocation->x, allocation->y,
allocation->width, allocation->height);
gdk_rectangle_union (out_clip, &icon_clip, out_clip);
}
static gboolean
gtk_builtin_icon_snapshot (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height)
{
GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget));
gtk_snapshot_offset (snapshot, x, y);
gtk_css_style_snapshot_icon (gtk_css_gadget_get_style (gadget),
snapshot,
width, height,
priv->image_type);
gtk_snapshot_offset (snapshot, -x, -y);
return FALSE;
}
static void
gtk_builtin_icon_style_changed (GtkCssGadget *gadget,
GtkCssStyleChange *change)
{
GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget));
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_FONT))
priv->strikethrough_valid = FALSE;
GTK_CSS_GADGET_CLASS (gtk_builtin_icon_parent_class)->style_changed (gadget, change);
}
static void
gtk_builtin_icon_class_init (GtkBuiltinIconClass *klass)
{
GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass);
gadget_class->get_preferred_size = gtk_builtin_icon_get_preferred_size;
gadget_class->allocate = gtk_builtin_icon_allocate;
gadget_class->snapshot = gtk_builtin_icon_snapshot;
gadget_class->style_changed = gtk_builtin_icon_style_changed;
}
static void
gtk_builtin_icon_init (GtkBuiltinIcon *custom_gadget)
{
}
GtkCssGadget *
gtk_builtin_icon_new_for_node (GtkCssNode *node,
GtkWidget *owner)
{
return g_object_new (GTK_TYPE_BUILTIN_ICON,
"node", node,
"owner", owner,
NULL);
}
GtkCssGadget *
gtk_builtin_icon_new (const char *name,
GtkWidget *owner,
GtkCssGadget *parent,
GtkCssGadget *next_sibling)
{
GtkCssNode *node;
GtkCssGadget *result;
node = gtk_css_node_new ();
gtk_css_node_set_name (node, g_intern_string (name));
if (parent)
gtk_css_node_insert_before (gtk_css_gadget_get_node (parent),
node,
next_sibling ? gtk_css_gadget_get_node (next_sibling) : NULL);
result = gtk_builtin_icon_new_for_node (node, owner);
g_object_unref (node);
return result;
}
void
gtk_builtin_icon_set_image (GtkBuiltinIcon *icon,
GtkCssImageBuiltinType image)
{
GtkBuiltinIconPrivate *priv;
g_return_if_fail (GTK_IS_BUILTIN_ICON (icon));
priv = gtk_builtin_icon_get_instance_private (icon);
if (priv->image_type != image)
{
priv->image_type = image;
gtk_widget_queue_draw (gtk_css_gadget_get_owner (GTK_CSS_GADGET (icon)));
}
}
GtkCssImageBuiltinType
gtk_builtin_icon_get_image (GtkBuiltinIcon *icon)
{
GtkBuiltinIconPrivate *priv;
g_return_val_if_fail (GTK_IS_BUILTIN_ICON (icon), GTK_CSS_IMAGE_BUILTIN_NONE);
priv = gtk_builtin_icon_get_instance_private (icon);
return priv->image_type;
}
void
gtk_builtin_icon_set_default_size (GtkBuiltinIcon *icon,
int default_size)
{
GtkBuiltinIconPrivate *priv;
g_return_if_fail (GTK_IS_BUILTIN_ICON (icon));
priv = gtk_builtin_icon_get_instance_private (icon);
if (priv->default_size != default_size)
{
priv->default_size = default_size;
gtk_widget_queue_resize (gtk_css_gadget_get_owner (GTK_CSS_GADGET (icon)));
}
}
int
gtk_builtin_icon_get_default_size (GtkBuiltinIcon *icon)
{
GtkBuiltinIconPrivate *priv;
g_return_val_if_fail (GTK_IS_BUILTIN_ICON (icon), GTK_CSS_IMAGE_BUILTIN_NONE);
priv = gtk_builtin_icon_get_instance_private (icon);
return priv->default_size;
}
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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_BUILTIN_ICON_PRIVATE_H__
#define __GTK_BUILTIN_ICON_PRIVATE_H__
#include "gtk/gtkcssgadgetprivate.h"
G_BEGIN_DECLS
#define GTK_TYPE_BUILTIN_ICON (gtk_builtin_icon_get_type ())
#define GTK_BUILTIN_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_BUILTIN_ICON, GtkBuiltinIcon))
#define GTK_BUILTIN_ICON_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_BUILTIN_ICON, GtkBuiltinIconClass))
#define GTK_IS_BUILTIN_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_BUILTIN_ICON))
#define GTK_IS_BUILTIN_ICON_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_BUILTIN_ICON))
#define GTK_BUILTIN_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_BUILTIN_ICON, GtkBuiltinIconClass))
typedef struct _GtkBuiltinIcon GtkBuiltinIcon;
typedef struct _GtkBuiltinIconClass GtkBuiltinIconClass;
struct _GtkBuiltinIcon
{
GtkCssGadget parent;
};
struct _GtkBuiltinIconClass
{
GtkCssGadgetClass parent_class;
};
GType gtk_builtin_icon_get_type (void) G_GNUC_CONST;
GtkCssGadget * gtk_builtin_icon_new (const char *name,
GtkWidget *owner,
GtkCssGadget *parent,
GtkCssGadget *next_sibling);
GtkCssGadget * gtk_builtin_icon_new_for_node (GtkCssNode *node,
GtkWidget *owner);
void gtk_builtin_icon_set_image (GtkBuiltinIcon *icon,
GtkCssImageBuiltinType image);
GtkCssImageBuiltinType gtk_builtin_icon_get_image (GtkBuiltinIcon *icon);
void gtk_builtin_icon_set_default_size (GtkBuiltinIcon *icon,
int default_size);
int gtk_builtin_icon_get_default_size (GtkBuiltinIcon *icon);
G_END_DECLS
#endif /* __GTK_BUILTIN_ICON_PRIVATE_H__ */
+152 -22
View File
@@ -47,7 +47,7 @@
*
* Button-like widgets like #GtkToggleButton, #GtkMenuButton, #GtkVolumeButton,
* #GtkLockButton, #GtkColorButton, #GtkFontButton or #GtkFileChooserButton use
* style classes such as .toggle, .popup, .scale, .lock, .color, .file
* style classes such as .toggle, .popup, .scale, .lock, .color, .font, .file
* to differentiate themselves from a plain GtkButton.
*/
@@ -70,6 +70,7 @@
#include "a11y/gtkbuttonaccessible.h"
#include "gtkapplicationprivate.h"
#include "gtkactionhelper.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkcontainerprivate.h"
/* Time out before giving up on getting a key release when animating
@@ -119,6 +120,9 @@ static void gtk_button_get_property (GObject *object,
static void gtk_button_screen_changed (GtkWidget *widget,
GdkScreen *previous_screen);
static void gtk_button_unrealize (GtkWidget * widget);
static void gtk_button_size_allocate (GtkWidget * widget,
GtkAllocation * allocation);
static void gtk_button_snapshot (GtkWidget * widget, GtkSnapshot *snapshot);
static gint gtk_button_grab_broken (GtkWidget * widget,
GdkEventGrabBroken * event);
static gint gtk_button_key_release (GtkWidget * widget, GdkEventKey * event);
@@ -148,7 +152,27 @@ static void gtk_button_measure_ (GtkWidget *widget,
int *natural,
int *minimum_baseline,
int *natural_baseline);
static void gtk_button_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum_size,
int *natural_size,
int *minimum_baseline,
int *natural_baseline,
gpointer data);
static void gtk_button_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data);
static void gtk_button_set_child_type (GtkButton *button, guint child_type);
static gboolean gtk_button_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data);
static GParamSpec *props[LAST_PROP] = { NULL, };
static guint button_signals[LAST_SIGNAL] = { 0 };
@@ -180,13 +204,6 @@ gtk_button_remove (GtkContainer *container, GtkWidget *child)
GTK_CONTAINER_CLASS (gtk_button_parent_class)->remove (container, child);
}
static void
gtk_button_unmap (GtkWidget *widget)
{
GTK_BUTTON (widget)->priv->in_button = FALSE;
GTK_WIDGET_CLASS (gtk_button_parent_class)->unmap (widget);
}
static void
gtk_button_class_init (GtkButtonClass *klass)
{
@@ -206,13 +223,14 @@ gtk_button_class_init (GtkButtonClass *klass)
widget_class->measure = gtk_button_measure_;
widget_class->screen_changed = gtk_button_screen_changed;
widget_class->unrealize = gtk_button_unrealize;
widget_class->size_allocate = gtk_button_size_allocate;
widget_class->snapshot = gtk_button_snapshot;
widget_class->grab_broken_event = gtk_button_grab_broken;
widget_class->key_release_event = gtk_button_key_release;
widget_class->enter_notify_event = gtk_button_enter_notify;
widget_class->leave_notify_event = gtk_button_leave_notify;
widget_class->state_flags_changed = gtk_button_state_flags_changed;
widget_class->grab_notify = gtk_button_grab_notify;
widget_class->unmap = gtk_button_unmap;
container_class->add = gtk_button_add;
container_class->remove = gtk_button_remove;
@@ -335,11 +353,12 @@ touch_release_in_button (GtkButton *button)
}
gdk_event_get_coords (event, &x, &y);
gtk_widget_get_own_allocation (GTK_WIDGET (button), &allocation);
gtk_widget_get_allocation (GTK_WIDGET (button), &allocation);
gdk_event_free (event);
if (gdk_rectangle_contains_point (&allocation, x, y))
if (x >= 0 && x <= allocation.width &&
y >= 0 && y <= allocation.height)
return TRUE;
return FALSE;
@@ -383,10 +402,10 @@ multipress_gesture_update_cb (GtkGesture *gesture,
if (sequence != gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)))
return;
gtk_widget_get_own_allocation (GTK_WIDGET (button), &allocation);
gtk_widget_get_allocation (GTK_WIDGET (button), &allocation);
gtk_gesture_get_point (gesture, sequence, &x, &y);
in_button = gdk_rectangle_contains_point (&allocation, x, y);
in_button = (x >= 0 && y >= 0 && x < allocation.width && y < allocation.height);
if (priv->in_button != in_button)
{
@@ -446,6 +465,14 @@ gtk_button_init (GtkButton *button)
g_signal_connect (priv->gesture, "cancel", G_CALLBACK (multipress_gesture_cancel_cb), button);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_CAPTURE);
priv->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (button)),
GTK_WIDGET (button),
gtk_button_measure,
gtk_button_allocate,
gtk_button_render,
NULL,
NULL);
}
static void
@@ -455,6 +482,7 @@ gtk_button_finalize (GObject *object)
GtkButtonPrivate *priv = button->priv;
g_clear_object (&priv->gesture);
g_clear_object (&priv->gadget);
G_OBJECT_CLASS (gtk_button_parent_class)->finalize (object);
}
@@ -749,6 +777,73 @@ gtk_button_unrealize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_button_parent_class)->unrealize (widget);
}
static void
gtk_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkButton *button = GTK_BUTTON (widget);
GtkButtonPrivate *priv = button->priv;
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_button_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer unused)
{
GtkWidget *widget;
GtkWidget *child;
widget = gtk_css_gadget_get_owner (gadget);
*out_clip = *allocation;
child = gtk_bin_get_child (GTK_BIN (widget));
if (child && gtk_widget_get_visible (child))
{
GtkAllocation clip;
gtk_widget_size_allocate_with_baseline (child, (GtkAllocation *)allocation, baseline);
gtk_widget_get_clip (child, &clip);
gdk_rectangle_union (&clip, out_clip, out_clip);
}
}
static void
gtk_button_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
gtk_css_gadget_snapshot (GTK_BUTTON (widget)->priv->gadget, snapshot);
}
static gboolean
gtk_button_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkWidget *widget;
widget = gtk_css_gadget_get_owner (gadget);
GTK_WIDGET_CLASS (gtk_button_parent_class)->snapshot (widget, snapshot);
return gtk_widget_has_visible_focus (widget);
}
static void
gtk_button_do_release (GtkButton *button,
gboolean emit_clicked)
@@ -898,16 +993,22 @@ gtk_button_finish_activate (GtkButton *button,
gtk_button_clicked (button);
}
static void
gtk_button_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
gtk_button_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer data)
{
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
GtkWidget *widget;
GtkWidget *child;
widget = gtk_css_gadget_get_owner (gadget);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child && gtk_widget_get_visible (child))
{
@@ -917,6 +1018,31 @@ gtk_button_measure_ (GtkWidget *widget,
minimum, natural,
minimum_baseline, natural_baseline);
}
else
{
*minimum = 0;
*natural = 0;
if (minimum_baseline)
*minimum_baseline = 0;
if (natural_baseline)
*natural_baseline = 0;
}
}
static void
gtk_button_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
/**
@@ -1058,7 +1184,11 @@ gtk_button_update_state (GtkButton *button)
else
depressed = priv->in_button && priv->button_down;
new_state = gtk_widget_get_state_flags (GTK_WIDGET (button)) & ~(GTK_STATE_FLAG_ACTIVE);
new_state = gtk_widget_get_state_flags (GTK_WIDGET (button)) &
~(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE);
if (priv->in_button)
new_state |= GTK_STATE_FLAG_PRELIGHT;
if (depressed)
new_state |= GTK_STATE_FLAG_ACTIVE;
+3
View File
@@ -21,6 +21,7 @@
#include "gtkactionhelper.h"
#include "gtkgesturesingle.h"
#include "gtkcssgadgetprivate.h"
G_BEGIN_DECLS
@@ -28,6 +29,7 @@ G_BEGIN_DECLS
struct _GtkButtonPrivate
{
GtkActionHelper *action_helper;
GtkCssGadget *gadget;
GdkDevice *grab_keyboard;
@@ -36,6 +38,7 @@ struct _GtkButtonPrivate
guint activate_timeout;
guint button_down : 1;
guint constructed : 1;
guint in_button : 1;
guint use_underline : 1;
guint child_type : 2;
+445 -40
View File
@@ -82,7 +82,6 @@
#include "gtkrendericonprivate.h"
#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
#include "gtkwidgetprivate.h"
#define TIMEOUT_INITIAL 500
#define TIMEOUT_REPEAT 50
@@ -184,6 +183,9 @@ struct _GtkCalendarPrivate
{
GtkCalendarDisplayOptions display_flags;
GdkWindow *main_win;
GdkWindow *arrow_win[4];
gchar grow_space [32];
gint month;
@@ -257,6 +259,10 @@ static void gtk_calendar_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void gtk_calendar_realize (GtkWidget *widget);
static void gtk_calendar_unrealize (GtkWidget *widget);
static void gtk_calendar_map (GtkWidget *widget);
static void gtk_calendar_unmap (GtkWidget *widget);
static void gtk_calendar_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
@@ -264,10 +270,8 @@ static void gtk_calendar_measure (GtkWidget *widget,
int *natural,
int *minimum_baseline,
int *natural_baseline);
static void gtk_calendar_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
static void gtk_calendar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_calendar_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static gboolean gtk_calendar_button_press (GtkWidget *widget,
@@ -276,6 +280,10 @@ static gboolean gtk_calendar_button_release (GtkWidget *widget,
GdkEventButton *event);
static gboolean gtk_calendar_motion_notify (GtkWidget *widget,
GdkEventMotion *event);
static gboolean gtk_calendar_enter_notify (GtkWidget *widget,
GdkEventCrossing *event);
static gboolean gtk_calendar_leave_notify (GtkWidget *widget,
GdkEventCrossing *event);
static gboolean gtk_calendar_scroll (GtkWidget *widget,
GdkEventScroll *event);
static gboolean gtk_calendar_key_press (GtkWidget *widget,
@@ -328,6 +336,8 @@ static void calendar_invalidate_day (GtkCalendar *widget,
gint col);
static void calendar_invalidate_day_num (GtkCalendar *widget,
gint day);
static void calendar_invalidate_arrow (GtkCalendar *widget,
guint arrow);
static void calendar_compute_days (GtkCalendar *calendar);
static gint calendar_get_xsep (GtkCalendar *calendar);
@@ -353,12 +363,18 @@ gtk_calendar_class_init (GtkCalendarClass *class)
gobject_class->finalize = gtk_calendar_finalize;
widget_class->destroy = gtk_calendar_destroy;
widget_class->realize = gtk_calendar_realize;
widget_class->unrealize = gtk_calendar_unrealize;
widget_class->map = gtk_calendar_map;
widget_class->unmap = gtk_calendar_unmap;
widget_class->snapshot = gtk_calendar_snapshot;
widget_class->measure = gtk_calendar_measure;
widget_class->size_allocate = gtk_calendar_size_allocate;
widget_class->button_press_event = gtk_calendar_button_press;
widget_class->button_release_event = gtk_calendar_button_release;
widget_class->motion_notify_event = gtk_calendar_motion_notify;
widget_class->enter_notify_event = gtk_calendar_enter_notify;
widget_class->leave_notify_event = gtk_calendar_leave_notify;
widget_class->key_press_event = gtk_calendar_key_press;
widget_class->scroll_event = gtk_calendar_scroll;
widget_class->state_flags_changed = gtk_calendar_state_flags_changed;
@@ -524,6 +540,42 @@ gtk_calendar_class_init (GtkCalendarClass *class)
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkCalendar:inner-border:
*
* The spacing around the day/week headers and main area.
*/
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("inner-border",
P_("Inner border"),
P_("Inner border space"),
0, G_MAXINT, 4,
GTK_PARAM_READABLE));
/**
* GtkCalndar:vertical-separation:
*
* Separation between day headers and main area.
*/
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("vertical-separation",
P_("Vertical separation"),
P_("Space between day headers and main area"),
0, G_MAXINT, 4,
GTK_PARAM_READABLE));
/**
* GtkCalendar:horizontal-separation:
*
* Separation between week headers and main area.
*/
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("horizontal-separation",
P_("Horizontal separation"),
P_("Space between week headers and main area"),
0, G_MAXINT, 4,
GTK_PARAM_READABLE));
/**
* GtkCalendar::month-changed:
* @calendar: the object which received the signal.
@@ -663,9 +715,6 @@ gtk_calendar_init (GtkCalendar *calendar)
gtk_widget_set_can_focus (widget, TRUE);
gtk_widget_set_has_window (widget, FALSE);
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (calendar)),
GTK_STYLE_CLASS_VIEW);
if (!default_abbreviated_dayname[0])
for (i=0; i<7; i++)
{
@@ -1178,12 +1227,12 @@ calendar_arrow_rectangle (GtkCalendar *calendar,
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
int width, height;
GtkAllocation allocation;
GtkBorder padding;
gboolean year_left;
get_component_paddings (calendar, &padding, NULL, NULL, NULL);
gtk_widget_get_content_size (widget, &width, &height);
gtk_widget_get_allocation (widget, &allocation);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
year_left = priv->year_before;
@@ -1198,14 +1247,14 @@ calendar_arrow_rectangle (GtkCalendar *calendar,
{
case ARROW_MONTH_LEFT:
if (year_left)
rect->x = (width - padding.left - padding.right
rect->x = (allocation.width - padding.left - padding.right
- (3 + 2 * priv->arrow_width + priv->max_month_width));
else
rect->x = 3;
break;
case ARROW_MONTH_RIGHT:
if (year_left)
rect->x = (width - padding.left - padding.right
rect->x = (allocation.width - padding.left - padding.right
- 3 - priv->arrow_width);
else
rect->x = (priv->arrow_width + priv->max_month_width);
@@ -1214,19 +1263,16 @@ calendar_arrow_rectangle (GtkCalendar *calendar,
if (year_left)
rect->x = 3;
else
rect->x = (width - padding.left - padding.right
rect->x = (allocation.width - padding.left - padding.right
- (3 + 2 * priv->arrow_width + priv->max_year_width));
break;
case ARROW_YEAR_RIGHT:
if (year_left)
rect->x = (priv->arrow_width + priv->max_year_width);
else
rect->x = (width - padding.left - padding.right
rect->x = (allocation.width - padding.left - padding.right
- 3 - priv->arrow_width);
break;
default:
g_assert_not_reached();
}
rect->x += padding.left;
@@ -1472,23 +1518,198 @@ gtk_calendar_get_property (GObject *object,
}
}
/****************************************
* Realization *
****************************************/
static void
calendar_realize_arrows (GtkCalendar *calendar)
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
gint i;
GtkAllocation allocation;
if (! (priv->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE)
&& (priv->display_flags & GTK_CALENDAR_SHOW_HEADING))
{
gtk_widget_get_allocation (widget, &allocation);
for (i = 0; i < 4; i++)
{
GdkRectangle rect;
calendar_arrow_rectangle (calendar, i, &rect);
rect.x += allocation.x;
rect.y += allocation.y;
priv->arrow_win[i] = gdk_window_new_input (gtk_widget_get_window (widget),
GDK_ALL_EVENTS_MASK,
&rect);
gtk_widget_register_window (widget, priv->arrow_win[i]);
}
priv->arrow_prelight = 0x0;
}
else
{
for (i = 0; i < 4; i++)
priv->arrow_win[i] = NULL;
}
}
static void
calendar_unrealize_arrows (GtkCalendar *calendar)
{
GtkCalendarPrivate *priv = calendar->priv;
gint i;
for (i = 0; i < 4; i++)
{
if (priv->arrow_win[i])
{
gtk_widget_unregister_window (GTK_WIDGET (calendar), priv->arrow_win[i]);
gdk_window_destroy (priv->arrow_win[i]);
priv->arrow_win[i] = NULL;
}
}
}
static gint
calendar_get_inner_border (GtkCalendar *calendar)
{
return 4;
gint inner_border;
gtk_widget_style_get (GTK_WIDGET (calendar),
"inner-border", &inner_border,
NULL);
return inner_border;
}
static gint
calendar_get_xsep (GtkCalendar *calendar)
{
return 4;
gint xsep;
gtk_widget_style_get (GTK_WIDGET (calendar),
"horizontal-separation", &xsep,
NULL);
return xsep;
}
static gint
calendar_get_ysep (GtkCalendar *calendar)
{
gint ysep;
return 4;
gtk_widget_style_get (GTK_WIDGET (calendar),
"vertical-separation", &ysep,
NULL);
return ysep;
}
static void
gtk_calendar_realize (GtkWidget *widget)
{
GtkCalendarPrivate *priv = GTK_CALENDAR (widget)->priv;
gint inner_border = calendar_get_inner_border (GTK_CALENDAR (widget));
GtkAllocation allocation, rect;
GtkBorder padding;
get_component_paddings (GTK_CALENDAR (widget), &padding, NULL, NULL, NULL);
gtk_widget_get_allocation (widget, &allocation);
GTK_WIDGET_CLASS (gtk_calendar_parent_class)->realize (widget);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
rect.x = priv->week_width + padding.left + inner_border;
else
rect.x = padding.left + inner_border;
rect.y = priv->header_h + priv->day_name_h + padding.top + inner_border;
rect.width = allocation.width - rect.x - (padding.right + inner_border);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
rect.width -= priv->week_width;
rect.height = priv->main_h;
priv->main_win = gdk_window_new_input (gtk_widget_get_window (widget),
GDK_ALL_EVENTS_MASK,
&rect);
gtk_widget_register_window (widget, priv->main_win);
calendar_realize_arrows (GTK_CALENDAR (widget));
}
static void
gtk_calendar_unrealize (GtkWidget *widget)
{
GtkCalendarPrivate *priv = GTK_CALENDAR (widget)->priv;
calendar_unrealize_arrows (GTK_CALENDAR (widget));
if (priv->main_win)
{
gtk_widget_unregister_window (widget, priv->main_win);
gdk_window_destroy (priv->main_win);
priv->main_win = NULL;
}
GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unrealize (widget);
}
static void
calendar_map_arrows (GtkCalendar *calendar)
{
GtkCalendarPrivate *priv = calendar->priv;
gint i;
for (i = 0; i < 4; i++)
{
if (priv->arrow_win[i])
gdk_window_show (priv->arrow_win[i]);
}
}
static void
calendar_unmap_arrows (GtkCalendar *calendar)
{
GtkCalendarPrivate *priv = calendar->priv;
gint i;
for (i = 0; i < 4; i++)
{
if (priv->arrow_win[i])
gdk_window_hide (priv->arrow_win[i]);
}
}
static void
gtk_calendar_map (GtkWidget *widget)
{
GtkCalendarPrivate *priv = GTK_CALENDAR (widget)->priv;
GTK_WIDGET_CLASS (gtk_calendar_parent_class)->map (widget);
gdk_window_show (priv->main_win);
calendar_map_arrows (GTK_CALENDAR (widget));
}
static void
gtk_calendar_unmap (GtkWidget *widget)
{
GtkCalendarPrivate *priv = GTK_CALENDAR (widget)->priv;
calendar_unmap_arrows (GTK_CALENDAR (widget));
gdk_window_hide (priv->main_win);
GTK_WIDGET_CLASS (gtk_calendar_parent_class)->unmap (widget);
}
static gchar*
@@ -1828,18 +2049,18 @@ gtk_calendar_measure (GtkWidget *widget,
}
static void
gtk_calendar_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_calendar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = calendar->priv;
GtkBorder padding;
guint i;
gint inner_border = calendar_get_inner_border (calendar);
gint calendar_xsep = calendar_get_xsep (calendar);
get_component_paddings (calendar, &padding, NULL, NULL, NULL);
gtk_widget_set_allocation (widget, allocation);
if (priv->display_flags & GTK_CALENDAR_SHOW_WEEK_NUMBERS)
{
@@ -1860,9 +2081,47 @@ gtk_calendar_size_allocate (GtkWidget *widget,
- (DAY_XSEP * 6))/7;
priv->week_width = 0;
}
if (gtk_widget_get_realized (widget))
{
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
gdk_window_move_resize (priv->main_win,
allocation->x
+ priv->week_width + padding.left + inner_border,
allocation->y
+ priv->header_h + priv->day_name_h
+ (padding.top + inner_border),
allocation->width - priv->week_width
- (inner_border * 2) - padding.left - padding.right,
priv->main_h);
else
gdk_window_move_resize (priv->main_win,
allocation->x
+ padding.left + inner_border,
allocation->y
+ priv->header_h + priv->day_name_h
+ padding.top + inner_border,
allocation->width - priv->week_width
- (inner_border * 2) - padding.left - padding.right,
priv->main_h);
for (i = 0 ; i < 4 ; i++)
{
if (priv->arrow_win[i])
{
GdkRectangle rect;
calendar_arrow_rectangle (calendar, i, &rect);
gdk_window_move_resize (priv->arrow_win[i],
allocation->x + rect.x,
allocation->y + rect.y,
rect.width, rect.height);
}
}
}
}
/****************************************
* Repainting *
****************************************/
@@ -2184,7 +2443,24 @@ static void
calendar_invalidate_day_num (GtkCalendar *calendar,
gint day)
{
gtk_widget_queue_draw (GTK_WIDGET (calendar));
GtkCalendarPrivate *priv = calendar->priv;
gint r, c, row, col;
row = -1;
col = -1;
for (r = 0; r < 6; r++)
for (c = 0; c < 7; c++)
if (priv->day_month[r][c] == MONTH_CURRENT &&
priv->day[r][c] == day)
{
row = r;
col = c;
}
g_return_if_fail (row != -1);
g_return_if_fail (col != -1);
calendar_invalidate_day (calendar, row, col);
}
static void
@@ -2192,7 +2468,15 @@ calendar_invalidate_day (GtkCalendar *calendar,
gint row,
gint col)
{
gtk_widget_queue_draw (GTK_WIDGET (calendar));
GdkRectangle day_rect;
GtkAllocation allocation;
gtk_widget_get_allocation (GTK_WIDGET (calendar), &allocation);
calendar_day_rectangle (calendar, row, col, &day_rect);
gtk_widget_queue_draw_area (GTK_WIDGET (calendar),
allocation.x + day_rect.x,
allocation.y + day_rect.y,
day_rect.width, day_rect.height);
}
static gboolean
@@ -2367,6 +2651,27 @@ calendar_snapshot_main (GtkCalendar *calendar,
calendar_snapshot_day (calendar, snapshot, row, col);
}
static void
calendar_invalidate_arrow (GtkCalendar *calendar,
guint arrow)
{
GtkCalendarPrivate *priv = calendar->priv;
if (priv->display_flags & GTK_CALENDAR_SHOW_HEADING &&
priv->arrow_win[arrow])
{
GdkRectangle rect;
GtkAllocation allocation;
calendar_arrow_rectangle (calendar, arrow, &rect);
gtk_widget_get_allocation (GTK_WIDGET (calendar), &allocation);
gtk_widget_queue_draw_area (GTK_WIDGET (calendar),
allocation.x + rect.x,
allocation.y + rect.y,
rect.width, rect.height);
}
}
static void
calendar_snapshot_arrow (GtkCalendar *calendar,
GtkSnapshot *snapshot,
@@ -2379,6 +2684,9 @@ calendar_snapshot_arrow (GtkCalendar *calendar,
GtkStateFlags state;
GdkRectangle rect;
if (!priv->arrow_win[arrow])
return;
calendar_arrow_rectangle (calendar, arrow, &rect);
context = gtk_widget_get_style_context (widget);
@@ -2422,8 +2730,23 @@ gtk_calendar_snapshot (GtkWidget *widget,
{
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = calendar->priv;
GtkStyleContext *context;
int i;
context = gtk_widget_get_style_context (widget);
gtk_style_context_save (context);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
gtk_snapshot_render_background (snapshot, context, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_snapshot_render_frame (snapshot, context, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
gtk_style_context_restore (context);
calendar_snapshot_main (calendar, snapshot);
if (priv->display_flags & GTK_CALENDAR_SHOW_HEADING)
@@ -2533,15 +2856,21 @@ calendar_main_button_press (GtkCalendar *calendar,
{
GtkWidget *widget = GTK_WIDGET (calendar);
GtkCalendarPrivate *priv = calendar->priv;
double x, y;
gint x, y;
gint win_x, win_y;
gint row, col;
gint day_month;
gint day;
GtkAllocation allocation;
gdk_event_get_coords ((const GdkEvent *)event, &x, &y);
x = (gint) (event->x);
y = (gint) (event->y);
row = calendar_row_from_y (calendar, y);
col = calendar_column_from_x (calendar, x);
gdk_window_get_position (priv->main_win, &win_x, &win_y);
gtk_widget_get_allocation (widget, &allocation);
row = calendar_row_from_y (calendar, y + win_y - allocation.y);
col = calendar_column_from_x (calendar, x + win_x - allocation.x);
/* If row or column isn't found, just return. */
if (row == -1 || col == -1)
@@ -2587,24 +2916,18 @@ gtk_calendar_button_press (GtkWidget *widget,
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = calendar->priv;
gint arrow = -1;
double x, y;
if (!gtk_widget_has_focus (widget))
gtk_widget_grab_focus (widget);
gdk_event_get_coords ((const GdkEvent*)event, &x, &y);
if (y > priv->header_h)
if (event->window == priv->main_win)
calendar_main_button_press (calendar, event);
for (arrow = ARROW_YEAR_LEFT; arrow <= ARROW_MONTH_RIGHT; arrow++)
{
GdkRectangle arrow_rect;
calendar_arrow_rectangle (calendar, arrow, &arrow_rect);
if (gdk_rectangle_contains_point (&arrow_rect, (int)x, (int)y))
if (event->window == priv->arrow_win[arrow])
{
/* only call the action on single click, not double */
if (event->type == GDK_BUTTON_PRESS)
{
@@ -2667,6 +2990,74 @@ gtk_calendar_motion_notify (GtkWidget *widget,
return TRUE;
}
static gboolean
gtk_calendar_enter_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = calendar->priv;
if (event->window == priv->arrow_win[ARROW_MONTH_LEFT])
{
priv->arrow_prelight |= (1 << ARROW_MONTH_LEFT);
calendar_invalidate_arrow (calendar, ARROW_MONTH_LEFT);
}
if (event->window == priv->arrow_win[ARROW_MONTH_RIGHT])
{
priv->arrow_prelight |= (1 << ARROW_MONTH_RIGHT);
calendar_invalidate_arrow (calendar, ARROW_MONTH_RIGHT);
}
if (event->window == priv->arrow_win[ARROW_YEAR_LEFT])
{
priv->arrow_prelight |= (1 << ARROW_YEAR_LEFT);
calendar_invalidate_arrow (calendar, ARROW_YEAR_LEFT);
}
if (event->window == priv->arrow_win[ARROW_YEAR_RIGHT])
{
priv->arrow_prelight |= (1 << ARROW_YEAR_RIGHT);
calendar_invalidate_arrow (calendar, ARROW_YEAR_RIGHT);
}
return TRUE;
}
static gboolean
gtk_calendar_leave_notify (GtkWidget *widget,
GdkEventCrossing *event)
{
GtkCalendar *calendar = GTK_CALENDAR (widget);
GtkCalendarPrivate *priv = calendar->priv;
if (event->window == priv->arrow_win[ARROW_MONTH_LEFT])
{
priv->arrow_prelight &= ~(1 << ARROW_MONTH_LEFT);
calendar_invalidate_arrow (calendar, ARROW_MONTH_LEFT);
}
if (event->window == priv->arrow_win[ARROW_MONTH_RIGHT])
{
priv->arrow_prelight &= ~(1 << ARROW_MONTH_RIGHT);
calendar_invalidate_arrow (calendar, ARROW_MONTH_RIGHT);
}
if (event->window == priv->arrow_win[ARROW_YEAR_LEFT])
{
priv->arrow_prelight &= ~(1 << ARROW_YEAR_LEFT);
calendar_invalidate_arrow (calendar, ARROW_YEAR_LEFT);
}
if (event->window == priv->arrow_win[ARROW_YEAR_RIGHT])
{
priv->arrow_prelight &= ~(1 << ARROW_YEAR_RIGHT);
calendar_invalidate_arrow (calendar, ARROW_YEAR_RIGHT);
}
return TRUE;
}
static gboolean
gtk_calendar_scroll (GtkWidget *widget,
GdkEventScroll *event)
@@ -3129,6 +3520,13 @@ gtk_calendar_set_display_options (GtkCalendar *calendar,
&& (priv->display_flags & GTK_CALENDAR_SHOW_HEADING))
{
priv->display_flags &= ~GTK_CALENDAR_NO_MONTH_CHANGE;
calendar_realize_arrows (calendar);
if (gtk_widget_get_mapped (widget))
calendar_map_arrows (calendar);
}
else
{
calendar_unrealize_arrows (calendar);
}
}
@@ -3139,6 +3537,13 @@ gtk_calendar_set_display_options (GtkCalendar *calendar,
if (flags & GTK_CALENDAR_SHOW_HEADING)
{
priv->display_flags |= GTK_CALENDAR_SHOW_HEADING;
calendar_realize_arrows (calendar);
if (gtk_widget_get_mapped (widget))
calendar_map_arrows (calendar);
}
else
{
calendar_unrealize_arrows (calendar);
}
}
+50 -50
View File
@@ -23,6 +23,7 @@
#include "gtkaccelgroup.h"
#include "gtkmarshalers.h"
#include "gtklabel.h"
#include "gtkeventbox.h"
#include "gtkmain.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
@@ -67,7 +68,7 @@ static gchar *convert_keysym_state_to_string (GtkCellRendererAccel *accel,
guint keysym,
GdkModifierType mask,
guint keycode);
static GtkWidget *gtk_cell_editable_widget_new (GtkCellRenderer *cell,
static GtkWidget *gtk_cell_editable_event_box_new (GtkCellRenderer *cell,
GtkCellRendererAccelMode mode,
const gchar *path);
@@ -437,8 +438,8 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
GtkCellRendererText *celltext;
GtkCellRendererAccel *accel;
GtkWidget *label;
GtkWidget *editable;
gboolean is_editable;
GtkWidget *eventbox;
gboolean editable;
GdkDevice *device, *pointer;
GdkWindow *window;
@@ -447,8 +448,8 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
priv = accel->priv;
/* If the cell isn't editable we return NULL. */
g_object_get (celltext, "editable", &is_editable, NULL);
if (!is_editable)
g_object_get (celltext, "editable", &editable, NULL);
if (!editable)
return NULL;
window = gtk_widget_get_window (gtk_widget_get_toplevel (widget));
@@ -473,7 +474,7 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
priv->grab_pointer = pointer;
editable = gtk_cell_editable_widget_new (cell, priv->accel_mode, path);
eventbox = gtk_cell_editable_event_box_new (cell, priv->accel_mode, path);
label = gtk_label_new (NULL);
gtk_widget_set_halign (label, GTK_ALIGN_START);
@@ -486,11 +487,11 @@ gtk_cell_renderer_accel_start_editing (GtkCellRenderer *cell,
*/
gtk_label_set_text (GTK_LABEL (label), _("New accelerator…"));
gtk_container_add (GTK_CONTAINER (editable), label);
gtk_container_add (GTK_CONTAINER (eventbox), label);
gtk_grab_add (editable);
gtk_grab_add (eventbox);
return GTK_CELL_EDITABLE (editable);
return GTK_CELL_EDITABLE (eventbox);
}
static void
@@ -507,13 +508,12 @@ gtk_cell_renderer_accel_ungrab (GtkCellRendererAccel *accel)
/* --------------------------------- */
typedef struct _GtkCellEditableWidget GtkCellEditableWidget;
typedef GtkWidgetClass GtkCellEditableWidgetClass;
typedef struct _GtkCellEditableEventBox GtkCellEditableEventBox;
typedef GtkEventBoxClass GtkCellEditableEventBoxClass;
struct _GtkCellEditableWidget
struct _GtkCellEditableEventBox
{
GtkWidget parent;
GtkEventBox box;
gboolean editing_canceled;
GtkCellRendererAccelMode accel_mode;
gchar *path;
@@ -526,30 +526,30 @@ enum {
PROP_PATH
};
GType gtk_cell_editable_widget_get_type (void);
static void gtk_cell_editable_widget_cell_editable_init (GtkCellEditableIface *iface);
GType gtk_cell_editable_event_box_get_type (void);
static void gtk_cell_editable_event_box_cell_editable_init (GtkCellEditableIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkCellEditableWidget, gtk_cell_editable_widget, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE, gtk_cell_editable_widget_cell_editable_init))
G_DEFINE_TYPE_WITH_CODE (GtkCellEditableEventBox, gtk_cell_editable_event_box, GTK_TYPE_EVENT_BOX,
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE, gtk_cell_editable_event_box_cell_editable_init))
static void
gtk_cell_editable_widget_start_editing (GtkCellEditable *cell_editable,
GdkEvent *event)
gtk_cell_editable_event_box_start_editing (GtkCellEditable *cell_editable,
GdkEvent *event)
{
/* do nothing, because we are pointless */
}
static void
gtk_cell_editable_widget_cell_editable_init (GtkCellEditableIface *iface)
gtk_cell_editable_event_box_cell_editable_init (GtkCellEditableIface *iface)
{
iface->start_editing = gtk_cell_editable_widget_start_editing;
iface->start_editing = gtk_cell_editable_event_box_start_editing;
}
static gboolean
gtk_cell_editable_widget_key_press_event (GtkWidget *widget,
GdkEventKey *event)
gtk_cell_editable_event_box_key_press_event (GtkWidget *widget,
GdkEventKey *event)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)widget;
GtkCellEditableEventBox *box = (GtkCellEditableEventBox*)widget;
GdkModifierType accel_mods = 0;
guint accel_key;
guint keyval;
@@ -642,23 +642,23 @@ gtk_cell_editable_widget_key_press_event (GtkWidget *widget,
}
static void
gtk_cell_editable_widget_unrealize (GtkWidget *widget)
gtk_cell_editable_event_box_unrealize (GtkWidget *widget)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)widget;
GtkCellEditableEventBox *box = (GtkCellEditableEventBox*)widget;
gtk_grab_remove (widget);
gtk_cell_renderer_accel_ungrab (GTK_CELL_RENDERER_ACCEL (box->cell));
GTK_WIDGET_CLASS (gtk_cell_editable_widget_parent_class)->unrealize (widget);
GTK_WIDGET_CLASS (gtk_cell_editable_event_box_parent_class)->unrealize (widget);
}
static void
gtk_cell_editable_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
gtk_cell_editable_event_box_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)object;
GtkCellEditableEventBox *box = (GtkCellEditableEventBox*)object;
switch (prop_id)
{
@@ -678,12 +678,12 @@ gtk_cell_editable_widget_set_property (GObject *object,
}
static void
gtk_cell_editable_widget_get_property (GObject *object,
gtk_cell_editable_event_box_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)object;
GtkCellEditableEventBox *box = (GtkCellEditableEventBox*)object;
switch (prop_id)
{
@@ -703,27 +703,27 @@ gtk_cell_editable_widget_get_property (GObject *object,
}
static void
gtk_cell_editable_widget_finalize (GObject *object)
gtk_cell_editable_event_box_finalize (GObject *object)
{
GtkCellEditableWidget *box = (GtkCellEditableWidget*)object;
GtkCellEditableEventBox *box = (GtkCellEditableEventBox*)object;
g_free (box->path);
G_OBJECT_CLASS (gtk_cell_editable_widget_parent_class)->finalize (object);
G_OBJECT_CLASS (gtk_cell_editable_event_box_parent_class)->finalize (object);
}
static void
gtk_cell_editable_widget_class_init (GtkCellEditableWidgetClass *class)
gtk_cell_editable_event_box_class_init (GtkCellEditableEventBoxClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = gtk_cell_editable_widget_finalize;
object_class->set_property = gtk_cell_editable_widget_set_property;
object_class->get_property = gtk_cell_editable_widget_get_property;
object_class->finalize = gtk_cell_editable_event_box_finalize;
object_class->set_property = gtk_cell_editable_event_box_set_property;
object_class->get_property = gtk_cell_editable_event_box_get_property;
widget_class->key_press_event = gtk_cell_editable_widget_key_press_event;
widget_class->unrealize = gtk_cell_editable_widget_unrealize;
widget_class->key_press_event = gtk_cell_editable_event_box_key_press_event;
widget_class->unrealize = gtk_cell_editable_event_box_unrealize;
g_object_class_override_property (object_class,
PROP_EDITING_CANCELED,
@@ -743,19 +743,19 @@ gtk_cell_editable_widget_class_init (GtkCellEditableWidgetClass *class)
}
static void
gtk_cell_editable_widget_init (GtkCellEditableWidget *box)
gtk_cell_editable_event_box_init (GtkCellEditableEventBox *box)
{
gtk_widget_set_can_focus (GTK_WIDGET (box), TRUE);
}
static GtkWidget *
gtk_cell_editable_widget_new (GtkCellRenderer *cell,
GtkCellRendererAccelMode mode,
const gchar *path)
gtk_cell_editable_event_box_new (GtkCellRenderer *cell,
GtkCellRendererAccelMode mode,
const gchar *path)
{
GtkCellEditableWidget *box;
GtkCellEditableEventBox *box;
box = g_object_new (gtk_cell_editable_widget_get_type (),
box = g_object_new (gtk_cell_editable_event_box_get_type (),
"accel-mode", mode,
"path", path,
NULL);
-1
View File
@@ -26,7 +26,6 @@
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkspinbutton.h"
#include "gtkentry.h"
/**
+107 -16
View File
@@ -26,6 +26,7 @@
#include "gtkprivate.h"
#include "gtkorientableprivate.h"
#include "gtkrender.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkwidgetprivate.h"
#include <gobject/gmarshal.h>
#include "gtkbuildable.h"
@@ -66,10 +67,8 @@ static void gtk_cell_view_set_property (GObject *obj
GParamSpec *pspec);
static void gtk_cell_view_finalize (GObject *object);
static void gtk_cell_view_dispose (GObject *object);
static void gtk_cell_view_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
static void gtk_cell_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_cell_view_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static void gtk_cell_view_set_value (GtkCellView *cell_view,
@@ -98,7 +97,7 @@ static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable
gpointer *data);
static GtkSizeRequestMode gtk_cell_view_get_request_mode (GtkWidget *widget);
static void gtk_cell_view_measure (GtkWidget *widget,
static void gtk_cell_view_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
@@ -113,6 +112,27 @@ static void row_changed_cb (GtkTreeModel
GtkTreeIter *iter,
GtkCellView *view);
static void gtk_cell_view_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer data);
static void gtk_cell_view_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data);
static gboolean gtk_cell_view_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data);
struct _GtkCellViewPrivate
{
GtkTreeModel *model;
@@ -121,6 +141,8 @@ struct _GtkCellViewPrivate
GtkCellArea *area;
GtkCellAreaContext *context;
GtkCssGadget *gadget;
gulong size_changed_id;
gulong row_changed_id;
@@ -166,7 +188,7 @@ gtk_cell_view_class_init (GtkCellViewClass *klass)
widget_class->snapshot = gtk_cell_view_snapshot;
widget_class->size_allocate = gtk_cell_view_size_allocate;
widget_class->get_request_mode = gtk_cell_view_get_request_mode;
widget_class->measure = gtk_cell_view_measure;
widget_class->measure = gtk_cell_view_measure_;
/* properties */
g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation");
@@ -417,10 +439,21 @@ gtk_cell_view_set_property (GObject *object,
static void
gtk_cell_view_init (GtkCellView *cellview)
{
GtkCssNode *widget_node;
cellview->priv = gtk_cell_view_get_instance_private (cellview);
cellview->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
gtk_widget_set_has_window (GTK_WIDGET (cellview), FALSE);
widget_node = gtk_widget_get_css_node (GTK_WIDGET (cellview));
cellview->priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (cellview),
gtk_cell_view_measure,
gtk_cell_view_allocate,
gtk_cell_view_render,
NULL,
NULL);
}
static void
@@ -431,6 +464,8 @@ gtk_cell_view_finalize (GObject *object)
if (cellview->priv->displayed_row)
gtk_tree_row_reference_free (cellview->priv->displayed_row);
g_clear_object (&cellview->priv->gadget);
G_OBJECT_CLASS (gtk_cell_view_parent_class)->finalize (object);
}
@@ -460,15 +495,34 @@ gtk_cell_view_dispose (GObject *object)
}
static void
gtk_cell_view_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_cell_view_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (GTK_CELL_VIEW (widget)->priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_cell_view_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data)
{
GtkWidget *widget;
GtkCellView *cellview;
GtkCellViewPrivate *priv;
gint alloc_width, alloc_height, width, height;
widget = gtk_css_gadget_get_owner (gadget);
cellview = GTK_CELL_VIEW (widget);
priv = cellview->priv;
@@ -490,6 +544,8 @@ gtk_cell_view_size_allocate (GtkWidget *widget,
gtk_cell_area_context_allocate (priv->context, width, -1);
else if (alloc_height != allocation->height && priv->orientation == GTK_ORIENTATION_VERTICAL)
gtk_cell_area_context_allocate (priv->context, -1, height);
*out_clip = *allocation;
}
static void
@@ -552,8 +608,9 @@ gtk_cell_view_get_request_mode (GtkWidget *widget)
return gtk_cell_area_get_request_mode (priv->area);
}
static void
gtk_cell_view_measure (GtkWidget *widget,
gtk_cell_view_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
@@ -561,9 +618,28 @@ gtk_cell_view_measure (GtkWidget *widget,
int *minimum_baseline,
int *natural_baseline)
{
gtk_css_gadget_get_preferred_size (GTK_CELL_VIEW (widget)->priv->gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_cell_view_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer data)
{
GtkWidget *widget;
GtkCellView *cellview;
GtkCellViewPrivate *priv;
widget = gtk_css_gadget_get_owner (gadget);
cellview = GTK_CELL_VIEW (widget);
priv = cellview->priv;
@@ -649,22 +725,37 @@ static void
gtk_cell_view_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
gtk_css_gadget_snapshot (GTK_CELL_VIEW (widget)->priv->gadget, snapshot);
}
static gboolean
gtk_cell_view_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkWidget *widget;
GtkCellView *cellview;
GdkRectangle area;
GtkCellRendererState state;
widget = gtk_css_gadget_get_owner (gadget);
cellview = GTK_CELL_VIEW (widget);
/* render cells */
area.x = 0;
area.y = 0;
gtk_widget_get_content_size (widget, &area.width, &area.height);
area.x = x;
area.y = y;
area.width = width;
area.height = height;
/* set cell data (if available) */
if (cellview->priv->displayed_row)
gtk_cell_view_set_cell_data (cellview);
else if (cellview->priv->model)
return;
return FALSE;
if (gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_PRELIGHT)
state = GTK_CELL_RENDERER_PRELIT;
@@ -675,7 +766,7 @@ gtk_cell_view_snapshot (GtkWidget *widget,
gtk_cell_area_snapshot (cellview->priv->area, cellview->priv->context,
widget, snapshot, &area, &area, state, FALSE);
return FALSE;
}
static void
+33 -211
View File
@@ -24,32 +24,9 @@
* @Title: GtkCenterBox
* @See_also: #GtkBox
*
* The GtkCenterBox widget arranges three children in a horizontal
* The GtkCenterBox widget will arrange three children in a horizontal
* or vertical arrangement, keeping the middle child centered as well
* as possible.
*
* To add children to GtkCenterBox, use gtk_center_box_set_start_widget(),
* gtk_center_box_set_center_widget() and gtk_center_box_set_end_widget().
*
* The sizing and positioning of children can be influenced with the
* align and expand properties of the children.
*
* # GtkCenterBox as GtkBuildable
*
* The GtkCenterBox implementation of the #GtkBuildable interface supports
* placing children in the 3 positions by specifying start, center or
* end as the type attribute of a <child> element.
*
* # CSS nodes
*
* GtkCenterBox uses a single CSS node with the name box,
*
* In horizontal orientation, the nodes of the children are always arranged
* from left to right. So :first-child will always select the leftmost child,
* regardless of text direction.
*
* In vertical orientation, the nodes of the children are arranged from top to
* bottom.
*/
#include "config.h"
@@ -60,9 +37,6 @@
#include "gtkorientableprivate.h"
#include "gtkbuildable.h"
#include "gtksizerequest.h"
#include "gtktypebuiltins.h"
#include "gtkprivate.h"
#include "gtkintl.h"
struct _GtkCenterBox
{
@@ -73,7 +47,6 @@ struct _GtkCenterBox
GtkWidget *end_widget;
GtkOrientation orientation;
GtkBaselinePosition baseline_pos;
};
struct _GtkCenterBoxClass
@@ -84,7 +57,6 @@ struct _GtkCenterBoxClass
enum {
PROP_0,
PROP_BASELINE_POSITION,
PROP_ORIENTATION
};
@@ -116,16 +88,6 @@ gtk_center_box_buildable_init (GtkBuildableIface *iface)
iface->add_child = gtk_center_box_buildable_add_child;
}
static gboolean
get_expand (GtkWidget *widget,
GtkOrientation orientation)
{
if (orientation == GTK_ORIENTATION_HORIZONTAL)
return gtk_widget_get_hexpand (widget);
else
return gtk_widget_get_vexpand (widget);
}
static void
gtk_center_box_distribute (GtkCenterBox *self,
gint for_size,
@@ -169,21 +131,21 @@ gtk_center_box_distribute (GtkCenterBox *self,
if (self->center_widget)
{
center_size = CLAMP (size - (sizes[0].minimum_size + sizes[2].minimum_size), sizes[1].minimum_size, sizes[1].natural_size);
center_expand = get_expand (self->center_widget, self->orientation);
center_expand = gtk_widget_get_hexpand (self->center_widget);
}
if (self->start_widget)
{
avail = MIN ((size - center_size) / 2, size - (center_size + sizes[2].minimum_size));
start_size = CLAMP (avail, sizes[0].minimum_size, sizes[0].natural_size);
start_expand = get_expand (self->start_widget, self->orientation);
start_expand = gtk_widget_get_hexpand (self->start_widget);
}
if (self->end_widget)
{
avail = MIN ((size - center_size) / 2, size - (center_size + sizes[0].minimum_size));
end_size = CLAMP (avail, sizes[2].minimum_size, sizes[2].natural_size);
end_expand = get_expand (self->end_widget, self->orientation);
end_expand = gtk_widget_get_hexpand (self->end_widget);
}
if (self->center_widget)
@@ -207,7 +169,7 @@ gtk_center_box_distribute (GtkCenterBox *self,
start_size = center_pos;
if (end_expand)
end_size = size - (center_pos + center_size);
end_size = size - center_pos + center_size;
}
else
{
@@ -330,32 +292,13 @@ gtk_center_box_measure_opposite (GtkWidget *widget,
if (above_min >= 0)
{
int min_baseline = -1;
int nat_baseline = -1;
total_min = MAX (total_min, above_min + below_min);
total_nat = MAX (total_nat, above_nat + below_nat);
switch (self->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
min_baseline = above_min;
nat_baseline = above_nat;
break;
case GTK_BASELINE_POSITION_CENTER:
min_baseline = above_min + (total_min - (above_min + below_min)) / 2;
nat_baseline = above_nat + (total_nat - (above_nat + below_nat)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
min_baseline = total_min - below_min;
nat_baseline = total_nat - below_nat;
break;
}
/* assume GTK_BASELINE_POSITION_CENTER for now */
if (minimum_baseline)
*minimum_baseline = min_baseline;
*minimum_baseline = above_min + (total_min - (above_min + below_min)) / 2;
if (natural_baseline)
*natural_baseline = nat_baseline;
*natural_baseline = above_nat + (total_nat - (above_nat + below_nat)) / 2;
}
*minimum = total_min;
@@ -380,13 +323,12 @@ gtk_center_box_measure (GtkWidget *widget,
}
static void
gtk_center_box_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_center_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkCenterBox *self = GTK_CENTER_BOX (widget);
GtkAllocation child_allocation;
GtkAllocation clip = *allocation;
GtkAllocation child_clip;
GtkWidget *child[3];
int child_size[3];
@@ -394,12 +336,16 @@ gtk_center_box_size_allocate (GtkWidget *widget,
GtkRequestedSize sizes[3];
int size;
int for_size;
int baseline;
int i;
GTK_WIDGET_CLASS (gtk_center_box_parent_class)->size_allocate (widget, allocation);
if (self->orientation == GTK_ORIENTATION_HORIZONTAL)
{
size = allocation->width;
for_size = allocation->height;
baseline = gtk_widget_get_allocated_baseline (widget);
}
else
{
@@ -408,8 +354,6 @@ gtk_center_box_size_allocate (GtkWidget *widget,
baseline = -1;
}
/* Allocate child sizes */
gtk_center_box_distribute (self, for_size, size, sizes);
if (self->orientation == GTK_ORIENTATION_HORIZONTAL &&
@@ -432,65 +376,6 @@ gtk_center_box_size_allocate (GtkWidget *widget,
child_size[2] = sizes[2].minimum_size;
}
/* Determine baseline */
if (self->orientation == GTK_ORIENTATION_HORIZONTAL &&
baseline == -1)
{
int min_above, nat_above;
int min_below, nat_below;
gboolean have_baseline;
have_baseline = FALSE;
min_above = nat_above = 0;
min_below = nat_below = 0;
for (i = 0; i < 3; i++)
{
if (child[i] && gtk_widget_get_valign (child[i]) == GTK_ALIGN_BASELINE)
{
int child_min_height, child_nat_height;
int child_min_baseline, child_nat_baseline;
child_min_baseline = child_nat_baseline = -1;
gtk_widget_measure (child[i], GTK_ORIENTATION_VERTICAL,
child_size[i],
&child_min_height, &child_nat_height,
&child_min_baseline, &child_nat_baseline);
if (child_min_baseline >= 0)
{
have_baseline = TRUE;
min_below = MAX (min_below, child_min_height - child_min_baseline);
nat_below = MAX (nat_below, child_nat_height - child_nat_baseline);
min_above = MAX (min_above, child_min_baseline);
nat_above = MAX (nat_above, child_nat_baseline);
}
}
}
if (have_baseline)
{
/* TODO: This is purely based on the minimum baseline.
* When things fit we should use the natural one
*/
switch (self->baseline_pos)
{
case GTK_BASELINE_POSITION_TOP:
baseline = min_above;
break;
case GTK_BASELINE_POSITION_CENTER:
baseline = min_above + (allocation->height - (min_above + min_below)) / 2;
break;
case GTK_BASELINE_POSITION_BOTTOM:
baseline = allocation->height - min_below;
break;
}
}
}
/* Allocate child positions */
child_pos[0] = 0;
child_pos[1] = (size / 2) - (child_size[1] / 2);
child_pos[2] = size - child_size[2];
@@ -526,9 +411,12 @@ gtk_center_box_size_allocate (GtkWidget *widget,
child_allocation.height = child_size[i];
}
gtk_widget_size_allocate (child[i], &child_allocation, allocation->y + baseline, &child_clip);
gdk_rectangle_union (out_clip, &child_clip, out_clip);
gtk_widget_size_allocate_with_baseline (child[i], &child_allocation, baseline);
gtk_widget_get_clip (child[i], &child_clip);
gdk_rectangle_union (&clip, &clip, &child_clip);
}
gtk_widget_set_clip (widget, &clip);
}
static void
@@ -614,10 +502,6 @@ gtk_center_box_set_property (GObject *object,
switch (prop_id)
{
case PROP_BASELINE_POSITION:
gtk_center_box_set_baseline_position (self, g_value_get_enum (value));
break;
case PROP_ORIENTATION:
{
GtkOrientation orientation = g_value_get_enum (value);
@@ -647,10 +531,6 @@ gtk_center_box_get_property (GObject *object,
switch (prop_id)
{
case PROP_BASELINE_POSITION:
g_value_set_enum (value, self->baseline_pos);
break;
case PROP_ORIENTATION:
g_value_set_enum (value, self->orientation);
break;
@@ -678,15 +558,6 @@ gtk_center_box_class_init (GtkCenterBoxClass *klass)
g_object_class_override_property (object_class, PROP_ORIENTATION, "orientation");
g_object_class_install_property (object_class, PROP_BASELINE_POSITION,
g_param_spec_enum ("baseline-position",
P_("Baseline position"),
P_("The position of the baseline aligned widgets if extra space is available"),
GTK_TYPE_BASELINE_POSITION,
GTK_BASELINE_POSITION_CENTER,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_FILLER);
gtk_widget_class_set_css_name (widget_class, "box");
}
@@ -701,7 +572,6 @@ gtk_center_box_init (GtkCenterBox *self)
self->end_widget = NULL;
self->orientation = GTK_ORIENTATION_HORIZONTAL;
self->baseline_pos = GTK_BASELINE_POSITION_CENTER;
}
/**
@@ -722,9 +592,9 @@ gtk_center_box_new (void)
/**
* gtk_center_box_set_start_widget:
* @self: a #GtkCenterBox
* @child: (nullable): the new start widget, or %NULL
* @child: the child
*
* Sets the start widget. To remove the existing start widget, pass %NULL.
* Sets the start widget.
*
* Since: 3.92
*/
@@ -745,15 +615,15 @@ gtk_center_box_set_start_widget (GtkCenterBox *self,
/**
* gtk_center_box_set_center_widget:
* @self: a #GtkCenterBox
* @child: (nullable): the new center widget, or %NULL
* @child: the child
*
* Sets the center widget. To remove the existing center widget, pas %NULL.
* Sets the center widget.
*
* Since: 3.92
*/
void
gtk_center_box_set_center_widget (GtkCenterBox *self,
GtkWidget *child)
GtkWidget *child)
{
if (self->center_widget)
gtk_widget_unparent (self->center_widget);
@@ -768,9 +638,9 @@ gtk_center_box_set_center_widget (GtkCenterBox *self,
/**
* gtk_center_box_set_end_widget:
* @self: a #GtkCenterBox
* @child: (nullable): the new end widget, or %NULL
* @child: the child
*
* Sets the end widget. To remove the existing end widget, pass %NULL.
* Sets the end widget.
*
* Since: 3.92
*/
@@ -792,9 +662,9 @@ gtk_center_box_set_end_widget (GtkCenterBox *self,
* gtk_center_box_get_start_widget:
* @self: a #GtkCenterBox
*
* Gets the start widget, or %NULL if there is none.
* Gets the start widget.
*
* Returns: (transfer none) (nullable): the start widget.
* Returns: the start widget.
*
* Since: 3.92
*/
@@ -808,9 +678,9 @@ gtk_center_box_get_start_widget (GtkCenterBox *self)
* gtk_center_box_get_center_widget:
* @self: a #GtkCenterBox
*
* Gets the center widget, or %NULL if there is none.
* Gets the center widget.
*
* Returns: (transfer none) (nullable): the center widget.
* Returns: the center widget.
*
* Since: 3.92
*/
@@ -824,9 +694,9 @@ gtk_center_box_get_center_widget (GtkCenterBox *self)
* gtk_center_box_get_end_widget:
* @self: a #GtkCenterBox
*
* Gets the end widget, or %NULL if there is none.
* Gets the end widget.
*
* Returns: (transfer none) (nullable): the end widget.
* Returns: the end widget.
*
* Since: 3.92
*/
@@ -835,51 +705,3 @@ gtk_center_box_get_end_widget (GtkCenterBox *self)
{
return self->end_widget;
}
/**
* gtk_center_box_set_baseline_position:
* @self: a #GtkCenterBox
* @position: a #GtkBaselinePosition
*
* Sets the baseline position of a center box.
*
* This affects only horizontal boxes with at least one baseline
* aligned child. If there is more vertical space available than
* requested, and the baseline is not allocated by the parent then
* @position is used to allocate the baseline wrt. the extra space
* available.
*
* Since: 3.92
*/
void
gtk_center_box_set_baseline_position (GtkCenterBox *self,
GtkBaselinePosition position)
{
g_return_if_fail (GTK_IS_CENTER_BOX (self));
if (self->baseline_pos != position)
{
self->baseline_pos = position;
g_object_notify (G_OBJECT (self), "baseline-position");
gtk_widget_queue_resize (GTK_WIDGET (self));
}
}
/**
* gtk_center_box_get_baseline_position:
* @self: a #GtkCenterBox
*
* Gets the value set by gtk_center_box_set_baseline_position().
*
* Returns: the baseline position
*
* Since: 3.92
*/
GtkBaselinePosition
gtk_center_box_get_baseline_position (GtkCenterBox *self)
{
g_return_val_if_fail (GTK_IS_CENTER_BOX (self), GTK_BASELINE_POSITION_CENTER);
return self->baseline_pos;
}
-13
View File
@@ -22,14 +22,8 @@
#ifndef __GTK_CENTER_BOX_H__
#define __GTK_CENTER_BOX_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include "gtkwidget.h"
G_BEGIN_DECLS
#define GTK_TYPE_CENTER_BOX (gtk_center_box_get_type ())
#define GTK_CENTER_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CENTER_BOX, GtkCenterBox))
#define GTK_CENTER_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CENTER_BOX, GtkCenterBoxClass))
@@ -62,12 +56,5 @@ GtkWidget * gtk_center_box_get_center_widget (GtkCenterBox *self);
GDK_AVAILABLE_IN_3_92
GtkWidget * gtk_center_box_get_end_widget (GtkCenterBox *self);
GDK_AVAILABLE_IN_3_92
void gtk_center_box_set_baseline_position (GtkCenterBox *self,
GtkBaselinePosition position);
GDK_AVAILABLE_IN_3_92
GtkBaselinePosition gtk_center_box_get_baseline_position (GtkCenterBox *self);
G_END_DECLS
#endif
+92 -126
View File
@@ -33,12 +33,13 @@
#include "gtkprivate.h"
#include "gtkrender.h"
#include "gtkwidgetprivate.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkboxgadgetprivate.h"
#include "gtkcontainerprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkradiobutton.h"
#include "gtkiconprivate.h"
/**
@@ -78,12 +79,13 @@
static void gtk_check_button_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
GtkAllocation *allocation);
static void gtk_check_button_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
typedef struct {
GtkWidget *indicator_widget;
GtkCssGadget *gadget;
GtkCssGadget *indicator_gadget;
guint draw_indicator : 1;
guint inconsistent : 1;
@@ -119,9 +121,9 @@ gtk_check_button_update_node_state (GtkWidget *widget)
image_type = GTK_IS_RADIO_BUTTON (widget) ? GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT : GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT;
else
image_type = GTK_CSS_IMAGE_BUILTIN_NONE;
gtk_builtin_icon_set_image (GTK_BUILTIN_ICON (priv->indicator_gadget), image_type);
gtk_icon_set_image (GTK_ICON (priv->indicator_widget), image_type);
gtk_widget_set_state_flags (priv->indicator_widget, state, TRUE);
gtk_css_gadget_set_state (priv->indicator_gadget, state);
}
@@ -134,12 +136,28 @@ gtk_check_button_state_flags_changed (GtkWidget *widget,
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->state_flags_changed (widget, previous_state_flags);
}
static void
gtk_check_button_direction_changed (GtkWidget *widget,
GtkTextDirection previous_direction)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
gtk_box_gadget_reverse_children (GTK_BOX_GADGET (priv->gadget));
gtk_box_gadget_set_allocate_reverse (GTK_BOX_GADGET (priv->gadget),
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
gtk_box_gadget_set_align_reverse (GTK_BOX_GADGET (priv->gadget),
gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->direction_changed (widget, previous_direction);
}
static void
gtk_check_button_finalize (GObject *object)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (object));
gtk_widget_unparent (priv->indicator_widget);
g_clear_object (&priv->gadget);
g_clear_object (&priv->indicator_gadget);
G_OBJECT_CLASS (gtk_check_button_parent_class)->finalize (object);
}
@@ -148,20 +166,25 @@ static void
gtk_check_button_add (GtkContainer *container,
GtkWidget *widget)
{
_gtk_bin_set_child (GTK_BIN (container), widget);
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (container));
int pos;
if (gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL)
gtk_widget_insert_after (widget, GTK_WIDGET (container), NULL);
else
gtk_widget_set_parent (widget, GTK_WIDGET (container));
GTK_CONTAINER_CLASS (gtk_check_button_parent_class)->add (container, widget);
pos = gtk_widget_get_direction (GTK_WIDGET (container)) == GTK_TEXT_DIR_RTL ? 0 : 1;
gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), pos, widget);
gtk_box_gadget_set_gadget_expand (GTK_BOX_GADGET (priv->gadget), G_OBJECT (widget), TRUE);
}
static void
gtk_check_button_remove (GtkContainer *container,
GtkWidget *widget)
{
_gtk_bin_set_child (GTK_BIN (container), NULL);
gtk_widget_unparent (widget);
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (container));
gtk_box_gadget_remove_widget (GTK_BOX_GADGET (priv->gadget), widget);
GTK_CONTAINER_CLASS (gtk_check_button_parent_class)->remove (container, widget);
}
static void
@@ -174,41 +197,18 @@ gtk_check_button_measure (GtkWidget *widget,
int *natural_baseline)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
GtkWidget *child;
int indicator_min = 0;
int indicator_nat = 0;
int child_min = 0;
int child_nat = 0;
*minimum = 0;
*natural = 0;
GtkCssGadget *gadget;
if (priv->draw_indicator)
{
gtk_widget_measure (priv->indicator_widget, orientation, for_size,
&indicator_min, &indicator_nat, NULL, NULL);
}
gadget = priv->gadget;
else
gadget = GTK_BUTTON (widget)->priv->gadget;
child = gtk_bin_get_child (GTK_BIN (widget));
if (child)
{
gtk_widget_measure (child, orientation, for_size,
&child_min, &child_nat, minimum_baseline, natural_baseline);
}
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
*minimum = indicator_min + child_min;
*natural = indicator_nat + child_nat;
}
else /* VERTICAL */
{
*minimum = MAX (indicator_min, child_min);
*natural = MAX (indicator_nat, child_nat);
}
gtk_css_gadget_get_preferred_size (gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
@@ -254,40 +254,6 @@ gtk_check_button_get_property (GObject *object,
}
}
static void
gtk_check_button_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
GtkWidget *child;
if (priv->draw_indicator)
gtk_widget_snapshot_child (widget, priv->indicator_widget, snapshot);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child)
gtk_widget_snapshot_child (widget, child, snapshot);
}
static void
gtk_check_button_direction_changed (GtkWidget *widget,
GtkTextDirection previous_direction)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
if (previous_direction == GTK_TEXT_DIR_LTR)
{
/* Now RTL -> Move the indicator to the right */
gtk_widget_insert_before (priv->indicator_widget, widget, NULL);
}
else
{
/* Now LTR -> Move the indicator to the left */
gtk_widget_insert_after (priv->indicator_widget, widget, NULL);
}
}
static void
gtk_check_button_class_init (GtkCheckButtonClass *class)
{
@@ -333,12 +299,14 @@ draw_indicator_changed (GtkCheckButton *check_button)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
GtkCssNode *widget_node;
GtkCssNode *indicator_node;
widget_node = gtk_widget_get_css_node (GTK_WIDGET (check_button));
indicator_node = gtk_css_gadget_get_node (priv->indicator_gadget);
if (priv->draw_indicator)
{
gtk_widget_show (priv->indicator_widget);
gtk_css_node_set_visible (indicator_node, TRUE);
if (GTK_IS_RADIO_BUTTON (check_button))
{
gtk_css_node_remove_class (widget_node, g_quark_from_static_string ("radio"));
@@ -352,7 +320,7 @@ draw_indicator_changed (GtkCheckButton *check_button)
}
else
{
gtk_widget_hide (priv->indicator_widget);
gtk_css_node_set_visible (indicator_node, FALSE);
if (GTK_IS_RADIO_BUTTON (check_button))
{
gtk_css_node_add_class (widget_node, g_quark_from_static_string ("radio"));
@@ -370,6 +338,7 @@ static void
gtk_check_button_init (GtkCheckButton *check_button)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
GtkCssNode *widget_node;
priv->draw_indicator = TRUE;
@@ -377,10 +346,15 @@ gtk_check_button_init (GtkCheckButton *check_button)
gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (check_button)), "toggle");
priv->indicator_widget = gtk_icon_new ("check");
gtk_widget_set_halign (priv->indicator_widget, GTK_ALIGN_CENTER);
gtk_widget_set_valign (priv->indicator_widget, GTK_ALIGN_CENTER);
gtk_widget_set_parent (priv->indicator_widget, GTK_WIDGET (check_button));
widget_node = gtk_widget_get_css_node (GTK_WIDGET (check_button));
priv->gadget = gtk_box_gadget_new_for_node (widget_node, GTK_WIDGET (check_button));
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_HORIZONTAL);
gtk_box_gadget_set_draw_focus (GTK_BOX_GADGET (priv->gadget), TRUE);
priv->indicator_gadget = gtk_builtin_icon_new ("check",
GTK_WIDGET (check_button),
priv->gadget,
NULL);
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->indicator_gadget, FALSE, GTK_ALIGN_BASELINE);
gtk_check_button_update_node_state (GTK_WIDGET (check_button));
}
@@ -434,52 +408,44 @@ gtk_check_button_new_with_mnemonic (const gchar *label)
}
static void
gtk_check_button_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_check_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
GtkAllocation child_alloc = { 0 };
GdkRectangle child_clip;
GtkWidget *child;
gboolean is_rtl = _gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
int x = 0;
GtkButton *button = GTK_BUTTON (widget);
GtkCssGadget *gadget;
GdkRectangle clip;
if (priv->draw_indicator)
gadget = priv->gadget;
else
gadget = button->priv->gadget;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
if (gtk_widget_get_realized (widget))
{
child_alloc.y = allocation->y;
child_alloc.height = allocation->height;
gtk_widget_measure (priv->indicator_widget, GTK_ORIENTATION_HORIZONTAL, -1,
&child_alloc.width, NULL, NULL, NULL);
if (is_rtl)
{
x = 0;
child_alloc.x = allocation->x + allocation->width - child_alloc.width;
}
else
{
x = child_alloc.width;
child_alloc.x = allocation->x;
}
gtk_widget_size_allocate (priv->indicator_widget, &child_alloc, baseline, &child_clip);
gdk_rectangle_union (out_clip, &child_clip, out_clip);
GtkAllocation border_allocation;
gtk_css_gadget_get_border_allocation (gadget, &border_allocation, NULL);
}
}
child = gtk_bin_get_child (GTK_BIN (widget));
if (child)
{
child_alloc.x = allocation->x + x;
child_alloc.y = allocation->y;
child_alloc.width = allocation->width - child_alloc.width; /* Indicator width */
child_alloc.height = allocation->height;
static void
gtk_check_button_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
gtk_widget_size_allocate (child, &child_alloc, baseline, &child_clip);
gdk_rectangle_union (out_clip, &child_clip, out_clip);
}
if (!priv->draw_indicator)
GTK_WIDGET_CLASS (gtk_check_button_parent_class)->snapshot (widget, snapshot);
else
gtk_css_gadget_snapshot (priv->gadget, snapshot);
}
GtkCssNode *
@@ -487,7 +453,7 @@ gtk_check_button_get_indicator_node (GtkCheckButton *check_button)
{
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
return gtk_widget_get_css_node (priv->indicator_widget);
return gtk_css_gadget_get_node (priv->indicator_gadget);
}
/**
+98 -62
View File
@@ -23,6 +23,7 @@
*/
#include "config.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkcheckmenuitemprivate.h"
#include "gtkmenuitemprivate.h"
#include "gtkaccellabel.h"
@@ -33,7 +34,6 @@
#include "gtkcssnodeprivate.h"
#include "gtkcssstylepropertyprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkiconprivate.h"
/**
* SECTION:gtkcheckmenuitem
@@ -60,9 +60,12 @@
* with name check, which gets the .left or .right style class.
*/
#define INDICATOR_SIZE 16
struct _GtkCheckMenuItemPrivate
{
GtkWidget *indicator_widget;
GtkCssGadget *indicator_gadget;
guint active : 1;
guint draw_as_radio : 1;
@@ -81,9 +84,13 @@ enum {
PROP_DRAW_AS_RADIO
};
static void gtk_check_menu_item_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static void gtk_check_menu_item_activate (GtkMenuItem *menu_item);
static void gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
gint *requisition);
static void gtk_real_check_menu_item_snapshot_indicator (GtkCheckMenuItem *check_menu_item,
GtkSnapshot *snapshot);
static void gtk_check_menu_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -104,47 +111,53 @@ G_DEFINE_TYPE_WITH_CODE (GtkCheckMenuItem, gtk_check_menu_item, GTK_TYPE_MENU_IT
G_ADD_PRIVATE (GtkCheckMenuItem))
static void
gtk_check_menu_item_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_check_menu_item_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkAllocation child_clip;
GtkAllocation indicator_alloc;
GtkAllocation clip, widget_clip;
GtkAllocation content_alloc, indicator_alloc;
GtkCssGadget *menu_item_gadget;
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget);
GtkCheckMenuItemPrivate *priv = check_menu_item->priv;
gint toggle_size;
gint content_baseline, toggle_size;
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->size_allocate (widget,
allocation,
baseline,
out_clip);
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->size_allocate
(widget, allocation);
gtk_widget_measure (priv->indicator_widget,
GTK_ORIENTATION_HORIZONTAL,
-1,
&indicator_alloc.width, NULL,
NULL, NULL);
gtk_widget_measure (priv->indicator_widget,
GTK_ORIENTATION_VERTICAL,
-1,
&indicator_alloc.height, NULL,
NULL, NULL);
menu_item_gadget = _gtk_menu_item_get_gadget (GTK_MENU_ITEM (widget));
gtk_css_gadget_get_content_allocation (menu_item_gadget,
&content_alloc, &content_baseline);
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
GTK_ORIENTATION_HORIZONTAL,
-1,
&indicator_alloc.width, NULL,
NULL, NULL);
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
GTK_ORIENTATION_VERTICAL,
-1,
&indicator_alloc.height, NULL,
NULL, NULL);
toggle_size = GTK_MENU_ITEM (check_menu_item)->priv->toggle_size;
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
indicator_alloc.x = (toggle_size - indicator_alloc.width) / 2;
indicator_alloc.x = content_alloc.x +
(toggle_size - indicator_alloc.width) / 2;
else
indicator_alloc.x = allocation->width - toggle_size +
indicator_alloc.x = content_alloc.x + content_alloc.width - toggle_size +
(toggle_size - indicator_alloc.width) / 2;
indicator_alloc.y = (allocation->height - indicator_alloc.height) / 2;
indicator_alloc.y = content_alloc.y +
(content_alloc.height - indicator_alloc.height) / 2;
gtk_widget_size_allocate (priv->indicator_widget,
&indicator_alloc,
baseline,
&child_clip);
gdk_rectangle_union (out_clip, &child_clip, out_clip);
gtk_css_gadget_allocate (check_menu_item->priv->indicator_gadget,
&indicator_alloc,
content_baseline,
&clip);
gtk_widget_get_clip (widget, &widget_clip);
gdk_rectangle_union (&widget_clip, &clip, &widget_clip);
gtk_widget_set_clip (widget, &widget_clip);
}
static void
@@ -152,7 +165,7 @@ gtk_check_menu_item_finalize (GObject *object)
{
GtkCheckMenuItemPrivate *priv = GTK_CHECK_MENU_ITEM (object)->priv;
gtk_widget_unparent (priv->indicator_widget);
g_clear_object (&priv->indicator_gadget);
G_OBJECT_CLASS (gtk_check_menu_item_parent_class)->finalize (object);
}
@@ -200,11 +213,14 @@ gtk_check_menu_item_class_init (GtkCheckMenuItemClass *klass)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
widget_class->snapshot = gtk_check_menu_item_snapshot;
menu_item_class->activate = gtk_check_menu_item_activate;
menu_item_class->hide_on_activate = FALSE;
menu_item_class->toggle_size_request = gtk_check_menu_item_toggle_size_request;
klass->toggled = NULL;
klass->snapshot_indicator = gtk_real_check_menu_item_snapshot_indicator;
/**
* GtkCheckMenuItem::toggled:
@@ -327,11 +343,11 @@ gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item,
g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (menu_item));
check_menu_item = GTK_CHECK_MENU_ITEM (menu_item);
gtk_widget_measure (check_menu_item->priv->indicator_widget,
GTK_ORIENTATION_HORIZONTAL,
-1,
requisition, NULL,
NULL, NULL);
gtk_css_gadget_get_preferred_size (check_menu_item->priv->indicator_gadget,
GTK_ORIENTATION_HORIZONTAL,
-1,
requisition, NULL,
NULL, NULL);
}
/**
@@ -353,14 +369,13 @@ update_node_state (GtkCheckMenuItem *check_menu_item)
GtkStateFlags state;
state = gtk_widget_get_state_flags (GTK_WIDGET (check_menu_item));
state &= ~(GTK_STATE_FLAG_CHECKED | GTK_STATE_FLAG_INCONSISTENT);
if (priv->inconsistent)
state |= GTK_STATE_FLAG_INCONSISTENT;
if (priv->active)
state |= GTK_STATE_FLAG_CHECKED;
gtk_widget_set_state_flags (priv->indicator_widget, state, TRUE);
gtk_css_gadget_set_state (priv->indicator_gadget, state);
}
/**
@@ -440,7 +455,7 @@ gtk_check_menu_item_set_draw_as_radio (GtkCheckMenuItem *check_menu_item,
if (draw_as_radio != priv->draw_as_radio)
{
priv->draw_as_radio = draw_as_radio;
indicator_node = gtk_widget_get_css_node (priv->indicator_widget);
indicator_node = gtk_css_gadget_get_node (priv->indicator_gadget);
if (draw_as_radio)
gtk_css_node_set_name (indicator_node, I_("radio"));
else
@@ -478,11 +493,27 @@ gtk_check_menu_item_init (GtkCheckMenuItem *check_menu_item)
priv = check_menu_item->priv = gtk_check_menu_item_get_instance_private (check_menu_item);
priv->active = FALSE;
priv->indicator_widget = gtk_icon_new ("check");
gtk_widget_set_parent (priv->indicator_widget, GTK_WIDGET (check_menu_item));
priv->indicator_gadget =
gtk_builtin_icon_new ("check",
GTK_WIDGET (check_menu_item),
_gtk_menu_item_get_gadget (GTK_MENU_ITEM (check_menu_item)),
NULL);
update_node_state (check_menu_item);
}
static void
gtk_check_menu_item_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget);
if (GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->snapshot)
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->snapshot (widget, snapshot);
if (GTK_CHECK_MENU_ITEM_GET_CLASS (check_menu_item)->snapshot_indicator)
GTK_CHECK_MENU_ITEM_GET_CLASS (check_menu_item)->snapshot_indicator (check_menu_item, snapshot);
}
static void
gtk_check_menu_item_activate (GtkMenuItem *menu_item)
{
@@ -518,37 +549,42 @@ static void
gtk_check_menu_item_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir)
{
GtkCheckMenuItemPrivate *priv = GTK_CHECK_MENU_ITEM (widget)->priv;
GtkStyleContext *context;
GtkWidget *child;
GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget);
GtkCheckMenuItemPrivate *priv = check_menu_item->priv;
GtkCssNode *indicator_node, *widget_node, *node;
context = gtk_widget_get_style_context (priv->indicator_widget);
indicator_node = gtk_css_gadget_get_node (priv->indicator_gadget);
widget_node = gtk_widget_get_css_node (widget);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
gtk_css_node_remove_class (indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT));
gtk_css_node_add_class (indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT));
child = gtk_widget_get_last_child (widget);
if (child != priv->indicator_widget)
gtk_widget_insert_before (widget, priv->indicator_widget, NULL);
node = gtk_css_node_get_last_child (widget_node);
if (node != indicator_node)
gtk_css_node_insert_after (widget_node, indicator_node, node);
}
else
{
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
gtk_css_node_add_class (indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_LEFT));
gtk_css_node_remove_class (indicator_node, g_quark_from_static_string (GTK_STYLE_CLASS_RIGHT));
child = gtk_widget_get_first_child (widget);
if (child != priv->indicator_widget)
gtk_widget_insert_after (widget, priv->indicator_widget, NULL);
node = gtk_css_node_get_first_child (widget_node);
if (node != indicator_node)
gtk_css_node_insert_before (widget_node, indicator_node, node);
}
GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->direction_changed (widget, previous_dir);
}
static void
gtk_real_check_menu_item_snapshot_indicator (GtkCheckMenuItem *check_menu_item,
GtkSnapshot *snapshot)
{
gtk_css_gadget_snapshot (check_menu_item->priv->indicator_gadget, snapshot);
}
static void
gtk_check_menu_item_get_property (GObject *object,
guint prop_id,
@@ -621,8 +657,8 @@ _gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
update_node_state (check_menu_item);
}
GtkWidget *
_gtk_check_menu_item_get_indicator_widget (GtkCheckMenuItem *check_menu_item)
GtkCssGadget *
_gtk_check_menu_item_get_indicator_gadget (GtkCheckMenuItem *check_menu_item)
{
return check_menu_item->priv->indicator_widget;
return check_menu_item->priv->indicator_gadget;
}
+3
View File
@@ -59,6 +59,7 @@ struct _GtkCheckMenuItem
* GtkCheckMenuItemClass:
* @parent_class: The parent class.
* @toggled: Signal emitted when the state of the check box is changed.
* @draw_indicator: Called to draw the check indicator.
*/
struct _GtkCheckMenuItemClass
{
@@ -67,6 +68,8 @@ struct _GtkCheckMenuItemClass
/*< public >*/
void (* toggled) (GtkCheckMenuItem *check_menu_item);
void (* snapshot_indicator) (GtkCheckMenuItem *check_menu_item,
GtkSnapshot *snapshot);
/*< private >*/
+2 -1
View File
@@ -19,12 +19,13 @@
#define __GTK_CHECK_MENU_ITEM_PRIVATE_H__
#include <gtk/gtkcheckmenuitem.h>
#include <gtk/gtkcssgadgetprivate.h>
G_BEGIN_DECLS
void _gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item,
gboolean is_active);
GtkWidget * _gtk_check_menu_item_get_indicator_widget (GtkCheckMenuItem *check_menu_item);
GtkCssGadget * _gtk_check_menu_item_get_indicator_gadget (GtkCheckMenuItem *check_menu_item);
G_END_DECLS
+3 -22
View File
@@ -268,15 +268,6 @@ gtk_clipboard_get (GdkAtom selection)
return gtk_clipboard_get_for_display (gdk_display_get_default (), selection);
}
GtkClipboard *
gtk_clipboard_get_default (GdkDisplay *display)
{
g_return_val_if_fail (display != NULL, NULL);
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return gtk_clipboard_get_for_display (display, GDK_SELECTION_CLIPBOARD);
}
static void
clipboard_owner_destroyed (gpointer data)
{
@@ -512,11 +503,8 @@ void
gtk_clipboard_clear (GtkClipboard *clipboard)
{
clipboard_unset (clipboard);
#ifdef AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
[clipboard->pasteboard clearContents];
#else
[clipboard->pasteboard declareTypes:nil owner:nil];
#endif
[clipboard->pasteboard declareTypes:nil owner:nil];
}
static void
@@ -765,6 +753,7 @@ GdkPixbuf *
gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
{
GdkAtom target = gdk_atom_intern_static_string("image/tiff");
int i;
GtkSelectionData *data;
data = gtk_clipboard_wait_for_contents (clipboard, target);
@@ -1118,11 +1107,3 @@ _gtk_clipboard_store_all (void)
list = list->next;
}
}
GdkAtom
gtk_clipboard_get_selection (GtkClipboard *clipboard)
{
g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), GDK_NONE);
return clipboard->selection;
}
+7 -7
View File
@@ -48,7 +48,7 @@
* SECTION:gtkcolorbutton
* @Short_description: A button to launch a color selection dialog
* @Title: GtkColorButton
* @See_also: #GtkFontButton
* @See_also: #GtkColorSelectionDialog, #GtkFontButton
*
* The #GtkColorButton is a button which displays the currently selected
* color and allows to open a color selection dialog to change the color.
@@ -168,15 +168,15 @@ gtk_color_button_snapshot (GtkWidget *widget,
}
static void
gtk_color_button_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_color_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkColorButton *button = GTK_COLOR_BUTTON (widget);
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
gtk_widget_size_allocate (priv->button, allocation, baseline, out_clip);
GTK_WIDGET_CLASS (gtk_color_button_parent_class)->size_allocate (widget, allocation);
gtk_widget_size_allocate (priv->button, allocation);
}
static void
@@ -249,7 +249,7 @@ gtk_color_button_class_init (GtkColorButtonClass *klass)
* @widget: the object which received the signal.
*
* The ::color-set signal is emitted when the user selects a color.
* When handling this signal, use gtk_color_chooser_get_rgba() to
* When handling this signal, use gtk_color_button_get_rgba() to
* find out which color was just selected.
*
* Note that this signal is only emitted when the user
+4 -4
View File
@@ -179,13 +179,13 @@ create_surface (GtkColorPlane *plane)
}
static void
plane_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
plane_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkColorPlane *plane = GTK_COLOR_PLANE (widget);
GTK_WIDGET_CLASS (gtk_color_plane_parent_class)->size_allocate (widget, allocation);
create_surface (plane);
}
+113 -43
View File
@@ -28,7 +28,9 @@
#include "gtkmenushell.h"
#include "gtkprivate.h"
#include "gtkintl.h"
#include "gtkiconhelperprivate.h"
#include "gtkcssnodeprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkroundedboxprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkstylecontextprivate.h"
@@ -58,7 +60,8 @@ struct _GtkColorSwatchPrivate
GtkGesture *long_press_gesture;
GtkGesture *multipress_gesture;
GtkWidget *overlay_widget;
GtkCssGadget *gadget;
GtkCssGadget *overlay_gadget;
GtkWidget *popover;
};
@@ -83,14 +86,29 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE_WITH_PRIVATE (GtkColorSwatch, gtk_color_swatch, GTK_TYPE_WIDGET)
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
static void
swatch_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
gtk_css_gadget_snapshot (GTK_COLOR_SWATCH (widget)->priv->gadget, snapshot);
}
#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
static gboolean
gtk_color_swatch_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkWidget *widget;
GtkColorSwatch *swatch;
GtkStyleContext *context;
widget = gtk_css_gadget_get_owner (gadget);
swatch = GTK_COLOR_SWATCH (widget);
context = gtk_widget_get_style_context (widget);
@@ -98,16 +116,21 @@ swatch_snapshot (GtkWidget *widget,
{
cairo_pattern_t *pattern;
cairo_matrix_t matrix;
GtkAllocation border_allocation;
GtkAllocation allocation, border_allocation;
GskRoundedRect content_box;
gtk_widget_get_border_allocation (widget, &border_allocation);
gtk_widget_get_allocation (widget, &allocation);
gtk_css_gadget_get_border_allocation (gadget, &border_allocation, NULL);
border_allocation.x -= allocation.x;
border_allocation.y -= allocation.y;
gtk_rounded_boxes_init_for_style (NULL,
NULL,
&content_box,
gtk_style_context_lookup_style (context),
0, 0,
border_allocation.x,
border_allocation.y,
border_allocation.width,
border_allocation.height);
gtk_snapshot_push_rounded_clip (snapshot,
@@ -154,9 +177,10 @@ swatch_snapshot (GtkWidget *widget,
gtk_snapshot_pop (snapshot);
}
gtk_widget_snapshot_child (widget, swatch->priv->overlay_widget, snapshot);
}
gtk_css_gadget_snapshot (swatch->priv->overlay_gadget, snapshot);
return gtk_widget_has_visible_focus (widget);
}
static void
drag_set_color_icon (GdkDragContext *context,
@@ -248,6 +272,39 @@ swatch_drag_data_received (GtkWidget *widget,
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (widget), &color);
}
static void
gtk_color_swatch_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer unused)
{
GtkWidget *widget;
GtkColorSwatch *swatch;
gint w, h, min;
widget = gtk_css_gadget_get_owner (gadget);
swatch = GTK_COLOR_SWATCH (widget);
gtk_css_gadget_get_preferred_size (swatch->priv->overlay_gadget,
orientation,
-1,
minimum, natural,
NULL, NULL);
gtk_widget_get_size_request (widget, &w, &h);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
min = w < 0 ? 48 : w;
else
min = h < 0 ? 32 : h;
*minimum = MAX (*minimum, min);
*natural = MAX (*natural, min);
}
static gboolean
swatch_key_press (GtkWidget *widget,
GdkEventKey *event)
@@ -380,17 +437,30 @@ tap_action (GtkGestureMultiPress *gesture,
}
static void
swatch_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
swatch_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
gtk_widget_size_allocate (swatch->priv->overlay_widget, allocation, -1, out_clip);
GtkAllocation clip, clip2;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (swatch->priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_css_gadget_allocate (swatch->priv->overlay_gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip2);
gdk_rectangle_union (&clip, &clip2, &clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_color_swatch_measure (GtkWidget *widget,
gtk_color_swatch_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
@@ -398,25 +468,11 @@ gtk_color_swatch_measure (GtkWidget *widget,
int *minimum_baseline,
int *natural_baseline)
{
GtkColorSwatch *swatch;
gint w, h, min;
swatch = GTK_COLOR_SWATCH (widget);
gtk_widget_measure (swatch->priv->overlay_widget,
orientation,
-1,
minimum, natural,
NULL, NULL);
gtk_widget_get_size_request (widget, &w, &h);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
min = w < 0 ? 48 : w;
else
min = h < 0 ? 32 : h;
*minimum = MAX (*minimum, min);
*natural = MAX (*natural, min);
gtk_css_gadget_get_preferred_size (GTK_COLOR_SWATCH (widget)->priv->gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
@@ -431,14 +487,14 @@ swatch_popup_menu (GtkWidget *widget)
static void
update_icon (GtkColorSwatch *swatch)
{
GtkImage *image = GTK_IMAGE (swatch->priv->overlay_widget);
GtkIconHelper *icon_helper = GTK_ICON_HELPER (swatch->priv->overlay_gadget);
if (swatch->priv->icon)
gtk_image_set_from_icon_name (image, swatch->priv->icon, GTK_ICON_SIZE_BUTTON);
_gtk_icon_helper_set_icon_name (icon_helper, swatch->priv->icon, GTK_ICON_SIZE_BUTTON);
else if (gtk_widget_get_state_flags (GTK_WIDGET (swatch)) & GTK_STATE_FLAG_SELECTED)
gtk_image_set_from_icon_name (image, "object-select-symbolic", GTK_ICON_SIZE_BUTTON);
_gtk_icon_helper_set_icon_name (icon_helper, "object-select-symbolic", GTK_ICON_SIZE_BUTTON);
else
gtk_image_clear (image);
_gtk_icon_helper_clear (icon_helper);
}
static void
@@ -447,6 +503,9 @@ swatch_state_flags_changed (GtkWidget *widget,
{
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (widget);
gtk_css_gadget_set_state (swatch->priv->gadget, gtk_widget_get_state_flags (widget));
gtk_css_gadget_set_state (swatch->priv->overlay_gadget, gtk_widget_get_state_flags (widget));
update_icon (swatch);
GTK_WIDGET_CLASS (gtk_color_swatch_parent_class)->state_flags_changed (widget, previous_state);
@@ -512,7 +571,8 @@ swatch_finalize (GObject *object)
GtkColorSwatch *swatch = GTK_COLOR_SWATCH (object);
g_free (swatch->priv->icon);
gtk_widget_unparent (swatch->priv->overlay_widget);
g_clear_object (&swatch->priv->gadget);
g_clear_object (&swatch->priv->overlay_gadget);
G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
}
@@ -545,7 +605,7 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
object_class->finalize = swatch_finalize;
object_class->dispose = swatch_dispose;
widget_class->measure = gtk_color_swatch_measure;
widget_class->measure = gtk_color_swatch_measure_;
widget_class->snapshot = swatch_snapshot;
widget_class->drag_begin = swatch_drag_begin;
widget_class->drag_data_get = swatch_drag_data_get;
@@ -588,6 +648,8 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
static void
gtk_color_swatch_init (GtkColorSwatch *swatch)
{
GtkCssNode *widget_node;
swatch->priv = gtk_color_swatch_get_instance_private (swatch);
swatch->priv->use_alpha = TRUE;
swatch->priv->selectable = TRUE;
@@ -607,12 +669,20 @@ gtk_color_swatch_init (GtkColorSwatch *swatch)
g_signal_connect (swatch->priv->multipress_gesture, "pressed",
G_CALLBACK (tap_action), swatch);
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (swatch)), "activatable");
widget_node = gtk_widget_get_css_node (GTK_WIDGET (swatch));
swatch->priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (swatch),
gtk_color_swatch_measure,
NULL,
gtk_color_swatch_render,
NULL,
NULL);
gtk_css_gadget_add_class (swatch->priv->gadget, "activatable");
swatch->priv->overlay_gadget = gtk_icon_helper_new_named ("overlay", GTK_WIDGET (swatch));
_gtk_icon_helper_set_force_scale_pixbuf (GTK_ICON_HELPER (swatch->priv->overlay_gadget), TRUE);
gtk_css_node_set_parent (gtk_css_gadget_get_node (swatch->priv->overlay_gadget), widget_node);
swatch->priv->overlay_widget = g_object_new (GTK_TYPE_IMAGE,
"css-name", "overlay",
NULL);
gtk_widget_set_parent (swatch->priv->overlay_widget, GTK_WIDGET (swatch));
}
/* Public API {{{1 */
+106 -11
View File
@@ -26,6 +26,8 @@
#include "gtkcellrenderertext.h"
#include "gtkcellview.h"
#include "gtkcontainerprivate.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkeventbox.h"
#include "gtkframe.h"
#include "gtkiconprivate.h"
#include "gtkbox.h"
@@ -138,6 +140,8 @@ struct _GtkComboBoxPrivate
GtkWidget *popup_widget;
GtkCssGadget *gadget;
gulong inserted_id;
gulong deleted_id;
gulong reordered_id;
@@ -221,6 +225,7 @@ static void gtk_combo_box_cell_layout_init (GtkCellLayoutIface *iface);
static void gtk_combo_box_cell_editable_init (GtkCellEditableIface *iface);
static void gtk_combo_box_constructed (GObject *object);
static void gtk_combo_box_dispose (GObject *object);
static void gtk_combo_box_finalize (GObject *object);
static void gtk_combo_box_unmap (GtkWidget *widget);
static void gtk_combo_box_destroy (GtkWidget *widget);
@@ -347,14 +352,16 @@ G_DEFINE_TYPE_WITH_CODE (GtkComboBox, gtk_combo_box, GTK_TYPE_BIN,
/* common */
static void
gtk_combo_box_measure (GtkWidget *widget,
gtk_combo_box_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
int *natural_baseline,
gpointer data)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
GtkComboBoxPrivate *priv = combo_box->priv;
@@ -366,15 +373,18 @@ gtk_combo_box_measure (GtkWidget *widget,
}
static void
gtk_combo_box_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
gtk_combo_box_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
GtkComboBoxPrivate *priv = combo_box->priv;
gtk_widget_size_allocate (priv->box, allocation, baseline, out_clip);
gtk_widget_size_allocate_with_baseline (priv->box, (GtkAllocation *) allocation, baseline);
gtk_widget_get_clip (priv->box, out_clip);
if (gtk_widget_get_visible (priv->popup_widget))
{
@@ -400,6 +410,70 @@ gtk_combo_box_size_allocate (GtkWidget *widget,
}
}
static gboolean
gtk_combo_box_render (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
GtkComboBoxPrivate *priv = combo_box->priv;
gtk_widget_snapshot_child (widget,
priv->box, snapshot);
return FALSE;
}
static void
gtk_combo_box_measure_ (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
gint dummy;
/* https://bugzilla.gnome.org/show_bug.cgi?id=729496 */
if (natural == NULL)
natural = &dummy;
gtk_css_gadget_get_preferred_size (GTK_COMBO_BOX (widget)->priv->gadget,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_combo_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
gtk_css_gadget_allocate (GTK_COMBO_BOX (widget)->priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_combo_box_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
gtk_css_gadget_snapshot (GTK_COMBO_BOX (widget)->priv->gadget, snapshot);
}
static void
gtk_combo_box_compute_expand (GtkWidget *widget,
gboolean *hexpand,
@@ -437,10 +511,11 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
widget_class = (GtkWidgetClass *)klass;
widget_class->size_allocate = gtk_combo_box_size_allocate;
widget_class->snapshot = gtk_combo_box_snapshot;
widget_class->scroll_event = gtk_combo_box_scroll_event;
widget_class->mnemonic_activate = gtk_combo_box_mnemonic_activate;
widget_class->grab_focus = gtk_combo_box_grab_focus;
widget_class->measure = gtk_combo_box_measure;
widget_class->measure = gtk_combo_box_measure_;
widget_class->unmap = gtk_combo_box_unmap;
widget_class->destroy = gtk_combo_box_destroy;
widget_class->compute_expand = gtk_combo_box_compute_expand;
@@ -448,6 +523,7 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
object_class = (GObjectClass *)klass;
object_class->constructed = gtk_combo_box_constructed;
object_class->dispose = gtk_combo_box_dispose;
object_class->finalize = gtk_combo_box_finalize;
object_class->set_property = gtk_combo_box_set_property;
object_class->get_property = gtk_combo_box_get_property;
@@ -939,6 +1015,7 @@ static void
gtk_combo_box_init (GtkComboBox *combo_box)
{
GtkComboBoxPrivate *priv;
GtkCssNode *widget_node;
GtkStyleContext *context;
GtkTreeMenu *menu;
@@ -973,6 +1050,14 @@ gtk_combo_box_init (GtkComboBox *combo_box)
gtk_style_context_remove_class (context, "toggle");
gtk_style_context_add_class (context, "combo");
widget_node = gtk_widget_get_css_node (GTK_WIDGET (combo_box));
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
GTK_WIDGET (combo_box),
gtk_combo_box_measure,
gtk_combo_box_allocate,
gtk_combo_box_render,
NULL, NULL);
menu = GTK_TREE_MENU (priv->popup_widget);
_gtk_tree_menu_set_wrap_width (menu, priv->wrap_width);
_gtk_tree_menu_set_row_span_column (menu, priv->row_column);
@@ -1415,7 +1500,7 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
{
gint width, min_width, nat_width;
gtk_widget_get_content_allocation (GTK_WIDGET (combo_box), &content_allocation);
gtk_css_gadget_get_content_allocation (priv->gadget, &content_allocation, NULL);
width = content_allocation.width;
gtk_widget_set_size_request (priv->popup_widget, -1, -1);
gtk_widget_measure (priv->popup_widget, GTK_ORIENTATION_HORIZONTAL, -1,
@@ -1437,8 +1522,8 @@ gtk_combo_box_menu_popup (GtkComboBox *combo_box)
if (priv->wrap_width > 0 || priv->cell_view == NULL)
{
gtk_widget_get_border_allocation (GTK_WIDGET (combo_box), &border_allocation);
gtk_widget_get_content_allocation (GTK_WIDGET (combo_box), &content_allocation);
gtk_css_gadget_get_border_allocation (priv->gadget, &border_allocation, NULL);
gtk_css_gadget_get_content_allocation (priv->gadget, &content_allocation, NULL);
g_object_set (priv->popup_widget,
"anchor-hints", (GDK_ANCHOR_FLIP_Y |
@@ -2817,6 +2902,16 @@ gtk_combo_box_dispose (GObject* object)
G_OBJECT_CLASS (gtk_combo_box_parent_class)->dispose (object);
}
static void
gtk_combo_box_finalize (GObject *object)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (object);
g_clear_object (&combo_box->priv->gadget);
G_OBJECT_CLASS (gtk_combo_box_parent_class)->finalize (object);
}
static gboolean
gtk_cell_editable_key_press (GtkWidget *widget,
GdkEventKey *event,
+200 -19
View File
@@ -42,6 +42,7 @@
#include "gtkmarshalers.h"
#include "gtksizerequest.h"
#include "gtksizerequestcacheprivate.h"
#include "gtksnapshotprivate.h"
#include "gtkwidgetprivate.h"
#include "gtkwindow.h"
#include "gtkassistant.h"
@@ -59,6 +60,7 @@
* of forall().
*/
#define SPECIAL_CONTAINER(x) (GTK_IS_ASSISTANT (x) || \
GTK_IS_ACTION_BAR (x) || \
GTK_IS_POPOVER_MENU (x) || \
GTK_IS_SHORTCUTS_SECTION (x) || \
GTK_IS_SHORTCUTS_WINDOW (x))
@@ -318,6 +320,10 @@ static gboolean gtk_container_focus_move (GtkContainer *container
GtkDirectionType direction);
static void gtk_container_children_callback (GtkWidget *widget,
gpointer client_data);
static gint gtk_container_draw (GtkWidget *widget,
cairo_t *cr);
static void gtk_container_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static GtkSizeRequestMode gtk_container_get_request_mode (GtkWidget *widget);
static GtkWidgetPath * gtk_container_real_get_path_for_child (GtkContainer *container,
@@ -346,6 +352,10 @@ static void gtk_container_buildable_custom_finished (GtkBuildable *buildable,
const gchar *tagname,
gpointer data);
static gboolean gtk_container_should_propagate_draw (GtkContainer *container,
GtkWidget *child,
cairo_t *cr);
/* --- variables --- */
static GQuark vadjustment_key_id;
static GQuark hadjustment_key_id;
@@ -448,6 +458,8 @@ gtk_container_class_init (GtkContainerClass *class)
widget_class->destroy = gtk_container_destroy;
widget_class->compute_expand = gtk_container_compute_expand;
widget_class->snapshot = gtk_container_snapshot;
widget_class->draw = gtk_container_draw;
widget_class->focus = gtk_container_focus;
widget_class->get_request_mode = gtk_container_get_request_mode;
@@ -579,7 +591,8 @@ gtk_container_buildable_set_child_property (GtkContainer *container,
GError *error = NULL;
GObjectNotifyQueue *nqueue;
if (SPECIAL_CONTAINER (container))
if (_gtk_widget_get_parent (child) != (GtkWidget *)container &&
!SPECIAL_CONTAINER (container))
{
/* This can happen with internal children of complex widgets.
* Silently ignore the child properties in this case. We explicitly
@@ -1818,7 +1831,6 @@ gtk_container_real_check_resize (GtkContainer *container)
{
if (!_gtk_widget_is_toplevel (widget))
{
GtkAllocation clip;
gtk_widget_get_preferred_size (widget, &requisition, NULL);
gtk_widget_get_allocated_size (widget, &allocation, &baseline);
@@ -1826,7 +1838,7 @@ gtk_container_real_check_resize (GtkContainer *container)
allocation.width = requisition.width;
if (allocation.height < requisition.height)
allocation.height = requisition.height;
gtk_widget_size_allocate (widget, &allocation, baseline, &clip);
gtk_widget_size_allocate_with_baseline (widget, &allocation, baseline);
}
else
gtk_widget_queue_resize (widget);
@@ -2032,13 +2044,18 @@ gtk_container_compute_expand (GtkWidget *widget,
}
static void
gtk_container_real_set_focus_child (GtkContainer *container,
GtkWidget *focus_child)
gtk_container_real_set_focus_child (GtkContainer *container,
GtkWidget *child)
{
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (focus_child == NULL || GTK_IS_WIDGET (focus_child));
GtkWidget *focus_child;
/* Check for h/v adjustments and scroll to show the focus child if possible */
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (child == NULL || GTK_IS_WIDGET (child));
focus_child = gtk_widget_get_focus_child (GTK_WIDGET (container));
/* check for h/v adjustments
*/
if (focus_child)
{
GtkAdjustment *hadj;
@@ -2050,20 +2067,17 @@ gtk_container_real_set_focus_child (GtkContainer *container,
vadj = g_object_get_qdata (G_OBJECT (container), vadjustment_key_id);
if (hadj || vadj)
{
GtkWidget *child = focus_child;
while (gtk_widget_get_focus_child (focus_child))
focus_child = gtk_widget_get_focus_child (focus_child);
while (gtk_widget_get_focus_child (child))
child = gtk_widget_get_focus_child (child);
if (!gtk_widget_translate_coordinates (child, focus_child,
0, 0, &x, &y))
return;
gtk_widget_translate_coordinates (focus_child, focus_child,
0, 0, &x, &y);
_gtk_widget_get_allocation (focus_child, &allocation);
x += allocation.x;
y += allocation.y;
_gtk_widget_get_allocation (child, &allocation);
_gtk_widget_get_allocation (focus_child, &allocation);
if (vadj)
gtk_adjustment_clamp_page (vadj, y, y + allocation.height);
@@ -2926,6 +2940,91 @@ typedef struct {
int window_depth;
} ChildOrderInfo;
static void
gtk_container_draw_forall (GtkWidget *widget,
gpointer client_data)
{
struct {
GtkContainer *container;
GArray *child_infos;
cairo_t *cr;
} *data = client_data;
ChildOrderInfo info;
GList *siblings;
GdkWindow *window;
if (gtk_container_should_propagate_draw (data->container, widget, data->cr))
{
info.child = widget;
info.window_depth = G_MAXINT;
window = _gtk_widget_get_window (widget);
if (window != gtk_widget_get_window (GTK_WIDGET (data->container)))
{
siblings = gdk_window_peek_children (gdk_window_get_parent (window));
info.window_depth = g_list_index (siblings, window);
}
g_array_append_val (data->child_infos, info);
}
}
static gint
compare_children_for_draw (gconstpointer _a,
gconstpointer _b)
{
const ChildOrderInfo *a = _a;
const ChildOrderInfo *b = _b;
return b->window_depth - a->window_depth;
}
static gint
gtk_container_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkContainer *container = GTK_CONTAINER (widget);
GArray *child_infos;
int i;
ChildOrderInfo *child_info;
struct {
GtkContainer *container;
GArray *child_infos;
cairo_t *cr;
} data;
child_infos = g_array_new (FALSE, TRUE, sizeof (ChildOrderInfo));
data.container = container;
data.cr = cr;
data.child_infos = child_infos;
gtk_container_forall (container,
gtk_container_draw_forall,
&data);
g_array_sort (child_infos, compare_children_for_draw);
for (i = 0; i < child_infos->len; i++)
{
child_info = &g_array_index (child_infos, ChildOrderInfo, i);
gtk_container_propagate_draw (container, child_info->child, cr);
}
g_array_free (child_infos, TRUE);
return FALSE;
}
static void
gtk_container_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkWidget *child;
for (child = _gtk_widget_get_first_child (widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
gtk_widget_snapshot_child (widget, child, snapshot);
}
static gboolean
gtk_container_should_propagate_draw (GtkContainer *container,
GtkWidget *child,
@@ -2937,6 +3036,88 @@ gtk_container_should_propagate_draw (GtkContainer *container,
return TRUE;
}
static void
union_with_clip (GtkWidget *widget,
GtkAllocation *clip)
{
GtkAllocation widget_clip;
if (!gtk_widget_is_visible (widget) ||
!_gtk_widget_get_child_visible (widget))
return;
gtk_widget_get_clip (widget, &widget_clip);
if (clip->width == 0 || clip->height == 0)
*clip = widget_clip;
else
gdk_rectangle_union (&widget_clip, clip, clip);
}
void
gtk_container_get_children_clip (GtkContainer *container,
GtkAllocation *out_clip)
{
GtkWidget *child;
memset (out_clip, 0, sizeof (GtkAllocation));
for (child = _gtk_widget_get_first_child (GTK_WIDGET (container));
child != NULL;
child = _gtk_widget_get_next_sibling (child))
union_with_clip (child, out_clip);
}
static void
gtk_container_get_translation_to_child (GtkContainer *container,
GtkWidget *child,
int *x_out,
int *y_out)
{
GtkAllocation allocation;
GdkWindow *window, *w;
int x, y;
/* translate coordinates. Ugly business, that. */
if (!_gtk_widget_get_has_window (GTK_WIDGET (container)))
{
_gtk_widget_get_allocation (GTK_WIDGET (container), &allocation);
x = -allocation.x;
y = -allocation.y;
}
else
{
x = 0;
y = 0;
}
window = _gtk_widget_get_window (GTK_WIDGET (container));
for (w = _gtk_widget_get_window (child); w && w != window; w = gdk_window_get_parent (w))
{
int wx, wy;
gdk_window_get_position (w, &wx, &wy);
x += wx;
y += wy;
}
if (w == NULL)
{
x = 0;
y = 0;
}
if (!_gtk_widget_get_has_window (child))
{
_gtk_widget_get_allocation (child, &allocation);
x += allocation.x;
y += allocation.y;
}
*x_out = x;
*y_out = y;
}
/**
* gtk_container_propagate_draw:
* @container: a #GtkContainer
@@ -2966,7 +3147,7 @@ gtk_container_propagate_draw (GtkContainer *container,
GtkWidget *child,
cairo_t *cr)
{
GtkAllocation child_allocation;
int x, y;
g_return_if_fail (GTK_IS_CONTAINER (container));
g_return_if_fail (GTK_IS_WIDGET (child));
@@ -2976,10 +3157,10 @@ gtk_container_propagate_draw (GtkContainer *container,
if (!gtk_container_should_propagate_draw (container, child, cr))
return;
gtk_widget_get_allocation (child, &child_allocation);
gtk_container_get_translation_to_child (container, child, &x, &y);
cairo_save (cr);
cairo_translate (cr, child_allocation.x, child_allocation.y);
cairo_translate (cr, x, y);
gtk_widget_draw_internal (child, cr, TRUE);
+2
View File
@@ -36,6 +36,8 @@ GList * _gtk_container_focus_sort (GtkContainer *container,
void _gtk_container_stop_idle_sizer (GtkContainer *container);
void _gtk_container_maybe_start_idle_sizer (GtkContainer *container);
void gtk_container_get_children_clip (GtkContainer *container,
GtkAllocation *out_clip);
void gtk_container_set_focus_child (GtkContainer *container,
GtkWidget *child);
-4
View File
@@ -60,10 +60,6 @@ gtk_css_value_border_compute (GtkCssValue *value,
values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, style, parent_style);
changed |= (values[i] != value->values[i]);
}
else
{
values[i] = NULL;
}
}
if (!changed)
+309
View File
@@ -0,0 +1,309 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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>
*/
#include "config.h"
#include "gtkcsscustomgadgetprivate.h"
#include "gtkcssnodeprivate.h"
/*
* GtkCssCustomGadget is a subclass that lets widgets customize size
* requests, size allocation and drawing of gadgets. The gadget is passed
* to the callbacks as the first argument, and you can use gtk_css_gadget_get_owner()
* to obtain the widget. Note that the widgets style context is not saved,
* so if you want to query style properties or call gtk_render functions which
* take the style context as an argument, you should use
* gtk_style_context_save_to_node to make the gadget's CSS node take effect.
*
* The callbacks are
*
* GtkCssPreferredSizeFunc:
* @gadget: the #GtkCssCustomGadget
* @orientation: whether a width (ie horizontal) or height (ie vertical) is requested
* @for_size: the available size in the opposite direction, or -1
* @minimum: return location for the minimum size
* @natural: return location for the natural size
* @minimum_baseline: (nullable): return location for the baseline at minimum size
* @natural_baseline: (nullable): return location for the baseline at natural size
* @data: data provided when registering the callback
*
* The GtkCssPreferredSizeFunc is called to determine the content size in
* gtk_css_gadget_get_preferred_size(). @for_size is a content size (ie excluding
* CSS padding, border and margin) and the returned @minimum, @natural,
* @minimum_baseline, @natural_baseline should be content sizes excluding CSS
* padding, border and margin as well.
*
* Typically, GtkCssPreferredSizeFunc will query the size of sub-gadgets and
* child widgets that are placed relative to the gadget and determine its own
* needed size from the results. If the gadget has no sub-gadgets or child
* widgets that it needs to place, then a GtkCssPreferredSizeFunc is only
* needed if you want to enforce a minimum size independent of CSS min-width
* and min-height (e.g. if size-related style properties need to be supported
* for compatibility).
*
* GtkCssAllocateFunc:
* @gadget: the #GtkCssCustomGadget
* @allocation: the allocation
* @baseline: the baseline
* @out_clip: (out): return location for the content clip
* @data: data provided when registering the callback
*
* The GtkCssAllocateFunc is called to allocate the gadgets content in
* gtk_css_gadget_allocate(). @allocation and @baseline are content sizes
* (ie excluding CSS padding, border and margin).
*
* Typically, GtkCssAllocateFunc will allocate sub-gadgets and child widgets
* that are placed relative to the gadget, and merge their clips into the
* value returned as @out_clip. For clip handling in the main gadget of
* containers, gtk_container_get_children_clip() can be useful. Gadgets that
* don't have sub-gadgets of child widgets don't need a GtkCssAllocateFunc
* (although it is still required to call gtk_css_gadget_allocate() on them).
*
* Note that @out_clip *must* be set to meaningful values. If in doubt,
* just set it to the allocation.
*
* GtkCssSnapshotFunc:
* @gadget: the #GtkCssCustomGadget
* @snapshot: the snapshot to draw on
* @x: the x origin of the content area
* @y: the y origin of the content area
* @width: the width of the content area
* @height: the height of the content area
* @data: data provided when registering the callback
*
* The GtkCssSnapshotFunc is called to draw the gadgets content in
* gtk_css_gadget_draw(). It gets passed an untransformed cairo context
* and the coordinates of the area to draw the content in.
*
* Typically, GtkCssSnapshotFunc will draw sub-gadgets and child widgets
* that are placed relative to the gadget, as well as custom content
* such as icons, checkmarks, arrows or text.
*
* GtkCssSnapshotFunc:
* @gadget: the #GtkCssCustomGadget
* @snapshot: the snapshot to snapshot to
* @x: the x origin of the content area
* @y: the y origin of the content area
* @width: the width of the content area
* @height: the height of the content area
* @data: data provided when registering the callback
*
* The GtkCssSnapshotFunc is called to snapshot the gadget's content in
* gtk_css_gadget_snapshot(). It gets passed an untransformed cairo context
* and the coordinates of the area to draw the content in.
*
* Typically, GtkCssSnapshotFunc will draw sub-gadgets and child widgets
* that are placed relative to the gadget, as well as custom content
* such as icons, checkmarks, arrows or text.
*/
typedef struct _GtkCssCustomGadgetPrivate GtkCssCustomGadgetPrivate;
struct _GtkCssCustomGadgetPrivate {
GtkCssPreferredSizeFunc preferred_size_func;
GtkCssAllocateFunc allocate_func;
GtkCssSnapshotFunc snapshot_func;
gpointer data;
GDestroyNotify destroy_func;
};
G_DEFINE_TYPE_WITH_CODE (GtkCssCustomGadget, gtk_css_custom_gadget, GTK_TYPE_CSS_GADGET,
G_ADD_PRIVATE (GtkCssCustomGadget))
static void
gtk_css_custom_gadget_get_preferred_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline)
{
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (gadget));
if (priv->preferred_size_func)
return priv->preferred_size_func (gadget, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline,
priv->data);
else
return GTK_CSS_GADGET_CLASS (gtk_css_custom_gadget_parent_class)->get_preferred_size (gadget, orientation, for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
static void
gtk_css_custom_gadget_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (gadget));
if (priv->allocate_func)
return priv->allocate_func (gadget, allocation, baseline, out_clip, priv->data);
else
return GTK_CSS_GADGET_CLASS (gtk_css_custom_gadget_parent_class)->allocate (gadget, allocation, baseline, out_clip);
}
static gboolean
gtk_css_custom_gadget_snapshot (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height)
{
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (gadget));
if (priv->snapshot_func)
return priv->snapshot_func (gadget, snapshot, x, y, width, height, priv->data);
else
return FALSE;
}
static void
gtk_css_custom_gadget_finalize (GObject *object)
{
GtkCssCustomGadgetPrivate *priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (object));
if (priv->destroy_func)
priv->destroy_func (priv->data);
G_OBJECT_CLASS (gtk_css_custom_gadget_parent_class)->finalize (object);
}
static void
gtk_css_custom_gadget_class_init (GtkCssCustomGadgetClass *klass)
{
GtkCssGadgetClass *gadget_class = GTK_CSS_GADGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = gtk_css_custom_gadget_finalize;
gadget_class->get_preferred_size = gtk_css_custom_gadget_get_preferred_size;
gadget_class->allocate = gtk_css_custom_gadget_allocate;
gadget_class->snapshot = gtk_css_custom_gadget_snapshot;
}
static void
gtk_css_custom_gadget_init (GtkCssCustomGadget *custom_gadget)
{
}
/**
* gtk_css_custom_gadget_new_for_node:
* @node: the #GtkCssNode to use for the gadget
* @owner: the widget that the gadget belongs to
* @preferred_size_func: (nullable): the GtkCssPreferredSizeFunc to use
* @allocate_func: (nullable): the GtkCssAllocateFunc to use
* @snapshot_func: (nullable): the GtkCssSnapshotFunc to use
* @data: (nullable): user data to pass to the callbacks
* @destroy_func: (nullable): destroy notify for @data
*
* Creates a #GtkCssCustomGadget for an existing CSS node.
* This function is typically used in the widgets init function
* to create the main gadget for the widgets main CSS node (which
* is obtained with gtk_widget_get_css_node()), as well as other
* permanent sub-gadgets. Sub-gadgets that only exist sometimes
* (e.g. depending on widget properties) should be created and
* destroyed as needed. All gadgets should be destroyed in the
* finalize (or dispose) vfunc.
*
* Returns: (transfer full): the new gadget
*/
GtkCssGadget *
gtk_css_custom_gadget_new_for_node (GtkCssNode *node,
GtkWidget *owner,
GtkCssPreferredSizeFunc preferred_size_func,
GtkCssAllocateFunc allocate_func,
GtkCssSnapshotFunc snapshot_func,
gpointer data,
GDestroyNotify destroy_func)
{
GtkCssCustomGadgetPrivate *priv;
GtkCssGadget *result;
result = g_object_new (GTK_TYPE_CSS_CUSTOM_GADGET,
"node", node,
"owner", owner,
NULL);
priv = gtk_css_custom_gadget_get_instance_private (GTK_CSS_CUSTOM_GADGET (result));
priv->preferred_size_func = preferred_size_func;
priv->allocate_func = allocate_func;
priv->snapshot_func = snapshot_func;
priv->data = data;
priv->destroy_func = destroy_func;
return result;
}
/**
* gtk_css_custom_gadget_new:
* @name: the name for the CSS node
* @owner: the widget that the gadget belongs to
* @parent: the gadget that has the parent CSS node
* @next_sibling: the gadget that has the sibling CSS node
* @preferred_size_func: (nullable): the GtkCssPreferredSizeFunc to use
* @allocate_func: (nullable): the GtkCssAllocateFunc to use
* @snapshot_func: (nullable): the GtkCssSnapshotFunc to use
* @data: (nullable): user data to pass to the callbacks
* @destroy_func: (nullable): destroy notify for @data
*
* Creates a #GtkCssCustomGadget with a new CSS node which gets
* placed below the @parent's and before the @next_sibling's CSS node.
*
* Returns: (transfer full): the new gadget
*/
GtkCssGadget *
gtk_css_custom_gadget_new (const char *name,
GtkWidget *owner,
GtkCssGadget *parent,
GtkCssGadget *next_sibling,
GtkCssPreferredSizeFunc preferred_size_func,
GtkCssAllocateFunc allocate_func,
GtkCssSnapshotFunc snapshot_func,
gpointer data,
GDestroyNotify destroy_func)
{
GtkCssNode *node;
GtkCssGadget *result;
node = gtk_css_node_new ();
gtk_css_node_set_name (node, g_intern_string (name));
if (parent)
gtk_css_node_insert_before (gtk_css_gadget_get_node (parent),
node,
next_sibling ? gtk_css_gadget_get_node (next_sibling) : NULL);
result = gtk_css_custom_gadget_new_for_node (node,
owner,
preferred_size_func,
allocate_func,
snapshot_func,
data,
destroy_func);
g_object_unref (node);
return result;
}
+88
View File
@@ -0,0 +1,88 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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_CSS_CUSTOM_GADGET_PRIVATE_H__
#define __GTK_CSS_CUSTOM_GADGET_PRIVATE_H__
#include "gtk/gtkcssgadgetprivate.h"
G_BEGIN_DECLS
#define GTK_TYPE_CSS_CUSTOM_GADGET (gtk_css_custom_gadget_get_type ())
#define GTK_CSS_CUSTOM_GADGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_CUSTOM_GADGET, GtkCssCustomGadget))
#define GTK_CSS_CUSTOM_GADGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_CUSTOM_GADGET, GtkCssCustomGadgetClass))
#define GTK_IS_CSS_CUSTOM_GADGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_CUSTOM_GADGET))
#define GTK_IS_CSS_CUSTOM_GADGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_CUSTOM_GADGET))
#define GTK_CSS_CUSTOM_GADGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_CUSTOM_GADGET, GtkCssCustomGadgetClass))
typedef struct _GtkCssCustomGadget GtkCssCustomGadget;
typedef struct _GtkCssCustomGadgetClass GtkCssCustomGadgetClass;
typedef void (* GtkCssPreferredSizeFunc) (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline,
gpointer data);
typedef void (* GtkCssAllocateFunc) (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data);
typedef gboolean (* GtkCssSnapshotFunc) (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height,
gpointer data);
struct _GtkCssCustomGadget
{
GtkCssGadget parent;
};
struct _GtkCssCustomGadgetClass
{
GtkCssGadgetClass parent_class;
};
GType gtk_css_custom_gadget_get_type (void) G_GNUC_CONST;
GtkCssGadget * gtk_css_custom_gadget_new (const char *name,
GtkWidget *owner,
GtkCssGadget *parent,
GtkCssGadget *next_sibling,
GtkCssPreferredSizeFunc get_preferred_size_func,
GtkCssAllocateFunc allocate_func,
GtkCssSnapshotFunc snapshot_func,
gpointer data,
GDestroyNotify destroy_func);
GtkCssGadget * gtk_css_custom_gadget_new_for_node (GtkCssNode *node,
GtkWidget *owner,
GtkCssPreferredSizeFunc preferred_size_func,
GtkCssAllocateFunc allocate_func,
GtkCssSnapshotFunc snapshot_func,
gpointer data,
GDestroyNotify destroy_func);
G_END_DECLS
#endif /* __GTK_CSS_CUSTOM_GADGET_PRIVATE_H__ */
+1078
View File
File diff suppressed because it is too large Load Diff
+145
View File
@@ -0,0 +1,145 @@
/*
* Copyright © 2015 Red Hat Inc.
*
* 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_CSS_GADGET_PRIVATE_H__
#define __GTK_CSS_GADGET_PRIVATE_H__
#include <cairo.h>
#include <glib-object.h>
#include "gtk/gtkwidget.h"
#include "gtk/gtkcssstylechangeprivate.h"
#include "gtk/gtkcsstypesprivate.h"
G_BEGIN_DECLS
#define GTK_TYPE_CSS_GADGET (gtk_css_gadget_get_type ())
#define GTK_CSS_GADGET(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_GADGET, GtkCssGadget))
#define GTK_CSS_GADGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_GADGET, GtkCssGadgetClass))
#define GTK_IS_CSS_GADGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_GADGET))
#define GTK_IS_CSS_GADGET_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_GADGET))
#define GTK_CSS_GADGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_GADGET, GtkCssGadgetClass))
typedef struct _GtkCssGadget GtkCssGadget;
typedef struct _GtkCssGadgetClass GtkCssGadgetClass;
struct _GtkCssGadget
{
GObject parent;
};
struct _GtkCssGadgetClass
{
GObjectClass parent_class;
void (* get_preferred_size) (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline);
void (* allocate) (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
gboolean (* snapshot) (GtkCssGadget *gadget,
GtkSnapshot *snapshot,
int x,
int y,
int width,
int height);
void (* style_changed) (GtkCssGadget *gadget,
GtkCssStyleChange *change);
};
GType gtk_css_gadget_get_type (void) G_GNUC_CONST;
GtkCssNode * gtk_css_gadget_get_node (GtkCssGadget *gadget);
GtkCssStyle * gtk_css_gadget_get_style (GtkCssGadget *gadget);
GtkWidget * gtk_css_gadget_get_owner (GtkCssGadget *gadget);
void gtk_css_gadget_set_node (GtkCssGadget *gadget,
GtkCssNode *node);
void gtk_css_gadget_set_visible (GtkCssGadget *gadget,
gboolean visible);
gboolean gtk_css_gadget_get_visible (GtkCssGadget *gadget);
gboolean gtk_css_gadget_margin_box_contains_point (GtkCssGadget *gadget,
int x,
int y);
gboolean gtk_css_gadget_border_box_contains_point (GtkCssGadget *gadget,
int x,
int y);
gboolean gtk_css_gadget_content_box_contains_point (GtkCssGadget *gadget,
int x,
int y);
void gtk_css_gadget_get_margin_box (GtkCssGadget *gadget,
GtkAllocation *box);
void gtk_css_gadget_get_border_box (GtkCssGadget *gadget,
GtkAllocation *box);
void gtk_css_gadget_get_content_box (GtkCssGadget *gadget,
GtkAllocation *box);
void gtk_css_gadget_add_class (GtkCssGadget *gadget,
const char *name);
void gtk_css_gadget_remove_class (GtkCssGadget *gadget,
const char *name);
void gtk_css_gadget_set_state (GtkCssGadget *gadget,
GtkStateFlags state);
void gtk_css_gadget_add_state (GtkCssGadget *gadget,
GtkStateFlags state);
void gtk_css_gadget_remove_state (GtkCssGadget *gadget,
GtkStateFlags state);
void gtk_css_gadget_get_preferred_size (GtkCssGadget *gadget,
GtkOrientation orientation,
gint for_size,
gint *minimum,
gint *natural,
gint *minimum_baseline,
gint *natural_baseline);
void gtk_css_gadget_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip);
void gtk_css_gadget_snapshot (GtkCssGadget *gadget,
GtkSnapshot *snapshot);
void gtk_css_gadget_queue_resize (GtkCssGadget *gadget);
void gtk_css_gadget_queue_allocate (GtkCssGadget *gadget);
void gtk_css_gadget_queue_draw (GtkCssGadget *gadget);
void gtk_css_gadget_get_margin_allocation (GtkCssGadget *gadget,
GtkAllocation *allocation,
int *baseline);
void gtk_css_gadget_get_border_allocation (GtkCssGadget *gadget,
GtkAllocation *allocation,
int *baseline);
void gtk_css_gadget_get_content_allocation (GtkCssGadget *gadget,
GtkAllocation *allocation,
int *baseline);
G_END_DECLS
#endif /* __GTK_CSS_GADGET_PRIVATE_H__ */
+308
View File
@@ -81,6 +81,7 @@
typedef struct GtkCssRuleset GtkCssRuleset;
typedef struct _GtkCssScanner GtkCssScanner;
typedef struct _PropertyValue PropertyValue;
typedef struct _WidgetPropertyValue WidgetPropertyValue;
typedef enum ParserScope ParserScope;
typedef enum ParserSymbol ParserSymbol;
@@ -90,14 +91,24 @@ struct _PropertyValue {
GtkCssSection *section;
};
struct _WidgetPropertyValue {
WidgetPropertyValue *next;
char *name;
char *value;
GtkCssSection *section;
};
struct GtkCssRuleset
{
GtkCssSelector *selector;
GtkCssSelectorTree *selector_match;
WidgetPropertyValue *widget_style;
PropertyValue *styles;
GtkBitmask *set_styles;
guint n_styles;
guint owns_styles : 1;
guint owns_widget_style : 1;
};
struct _GtkCssScanner
@@ -134,6 +145,7 @@ static guint css_provider_signals[LAST_SIGNAL] = { 0 };
static void gtk_css_provider_finalize (GObject *object);
static void gtk_css_style_provider_iface_init (GtkStyleProviderIface *iface);
static void gtk_css_style_provider_private_iface_init (GtkStyleProviderPrivateInterface *iface);
static void widget_property_value_list_free (WidgetPropertyValue *head);
static void gtk_css_style_provider_emit_error (GtkStyleProviderPrivate *provider,
GtkCssSection *section,
const GError *error);
@@ -243,6 +255,8 @@ gtk_css_ruleset_init_copy (GtkCssRuleset *new,
/* First copy takes over ownership */
if (ruleset->owns_styles)
ruleset->owns_styles = FALSE;
if (ruleset->owns_widget_style)
ruleset->owns_widget_style = FALSE;
if (new->set_styles)
new->set_styles = _gtk_bitmask_copy (new->set_styles);
}
@@ -265,12 +279,82 @@ gtk_css_ruleset_clear (GtkCssRuleset *ruleset)
}
if (ruleset->set_styles)
_gtk_bitmask_free (ruleset->set_styles);
if (ruleset->owns_widget_style)
widget_property_value_list_free (ruleset->widget_style);
if (ruleset->selector)
_gtk_css_selector_free (ruleset->selector);
memset (ruleset, 0, sizeof (GtkCssRuleset));
}
static WidgetPropertyValue *
widget_property_value_new (char *name, GtkCssSection *section)
{
WidgetPropertyValue *value;
value = g_slice_new0 (WidgetPropertyValue);
value->name = name;
if (gtk_keep_css_sections)
value->section = gtk_css_section_ref (section);
return value;
}
static void
widget_property_value_free (WidgetPropertyValue *value)
{
g_free (value->value);
g_free (value->name);
if (value->section)
gtk_css_section_unref (value->section);
g_slice_free (WidgetPropertyValue, value);
}
static void
widget_property_value_list_free (WidgetPropertyValue *head)
{
WidgetPropertyValue *l, *next;
for (l = head; l != NULL; l = next)
{
next = l->next;
widget_property_value_free (l);
}
}
static WidgetPropertyValue *
widget_property_value_list_remove_name (WidgetPropertyValue *head, const char *name)
{
WidgetPropertyValue *l, **last;
last = &head;
for (l = head; l != NULL; l = l->next)
{
if (strcmp (l->name, name) == 0)
{
*last = l->next;
widget_property_value_free (l);
break;
}
last = &l->next;
}
return head;
}
static void
gtk_css_ruleset_add_style (GtkCssRuleset *ruleset,
char *name,
WidgetPropertyValue *value)
{
value->next = widget_property_value_list_remove_name (ruleset->widget_style, name);
ruleset->widget_style = value;
ruleset->owns_widget_style = TRUE;
}
static void
gtk_css_ruleset_add (GtkCssRuleset *ruleset,
GtkCssStyleProperty *property,
@@ -538,9 +622,92 @@ verify_tree_get_change_results (GtkCssProvider *provider,
}
static gboolean
gtk_css_provider_get_style_property (GtkStyleProvider *provider,
GtkWidgetPath *path,
GtkStateFlags state,
GParamSpec *pspec,
GValue *value)
{
GtkCssProvider *css_provider = GTK_CSS_PROVIDER (provider);
GtkCssProviderPrivate *priv = css_provider->priv;
WidgetPropertyValue *val;
GPtrArray *tree_rules;
GtkCssMatcher matcher;
gboolean found = FALSE;
gchar *prop_name;
gint i;
if (state == gtk_widget_path_iter_get_state (path, -1))
{
gtk_widget_path_ref (path);
}
else
{
path = gtk_widget_path_copy (path);
gtk_widget_path_iter_set_state (path, -1, state);
}
if (!_gtk_css_matcher_init (&matcher, path, NULL))
{
gtk_widget_path_unref (path);
return FALSE;
}
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, &matcher);
if (tree_rules)
{
verify_tree_match_results (css_provider, &matcher, tree_rules);
prop_name = g_strdup_printf ("-%s-%s",
g_type_name (pspec->owner_type),
pspec->name);
for (i = tree_rules->len - 1; i >= 0; i--)
{
GtkCssRuleset *ruleset = tree_rules->pdata[i];
if (ruleset->widget_style == NULL)
continue;
for (val = ruleset->widget_style; val != NULL; val = val->next)
{
if (strcmp (val->name, prop_name) == 0)
{
GtkCssScanner *scanner;
scanner = gtk_css_scanner_new (css_provider,
NULL,
val->section,
val->section != NULL ? gtk_css_section_get_file (val->section) : NULL,
val->value);
if (!val->section)
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_VALUE);
found = _gtk_css_style_funcs_parse_value (value, scanner->parser);
if (!val->section)
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
gtk_css_scanner_destroy (scanner);
break;
}
}
if (found)
break;
}
g_free (prop_name);
g_ptr_array_free (tree_rules, TRUE);
}
gtk_widget_path_unref (path);
return found;
}
static void
gtk_css_style_provider_iface_init (GtkStyleProviderIface *iface)
{
iface->get_style_property = gtk_css_provider_get_style_property;
}
static GtkCssValue *
@@ -749,6 +916,12 @@ css_provider_commit (GtkCssProvider *css_provider,
priv = css_provider->priv;
if (ruleset->styles == NULL && ruleset->widget_style == NULL)
{
g_slist_free_full (selectors, (GDestroyNotify) _gtk_css_selector_free);
return;
}
for (l = selectors; l; l = l->next)
{
GtkCssRuleset new;
@@ -1138,6 +1311,67 @@ parse_selector_list (GtkCssScanner *scanner)
return selectors;
}
static gboolean
name_is_style_property (const char *name)
{
if (name[0] != '-')
return FALSE;
if (g_str_has_prefix (name, "-gtk-"))
return FALSE;
return TRUE;
}
static void
warn_if_deprecated (GtkCssScanner *scanner,
const gchar *name)
{
gchar *n = NULL;
gchar *p;
const gchar *type_name;
const gchar *property_name;
GType type;
GTypeClass *class = NULL;
GParamSpec *pspec;
n = g_strdup (name);
/* skip initial - */
type_name = n + 1;
p = strchr (type_name, '-');
if (!p)
goto out;
p[0] = '\0';
property_name = p + 1;
type = g_type_from_name (type_name);
if (type == G_TYPE_INVALID ||
!g_type_is_a (type, GTK_TYPE_WIDGET))
goto out;
class = g_type_class_ref (type);
pspec = gtk_widget_class_find_style_property (GTK_WIDGET_CLASS (class), property_name);
if (!pspec)
goto out;
if (!(pspec->flags & G_PARAM_DEPRECATED))
goto out;
_gtk_css_parser_error_full (scanner->parser,
GTK_CSS_PROVIDER_ERROR_DEPRECATED,
"The style property %s:%s is deprecated and shouldn't be "
"used anymore. It will be removed in a future version",
g_type_name (pspec->owner_type), pspec->name);
out:
g_free (n);
if (class)
g_type_class_unref (class);
}
static void
parse_declaration (GtkCssScanner *scanner,
GtkCssRuleset *ruleset)
@@ -1152,6 +1386,19 @@ parse_declaration (GtkCssScanner *scanner,
goto check_for_semicolon;
property = _gtk_style_property_lookup (name);
if (property == NULL && !name_is_style_property (name))
{
gtk_css_provider_error (scanner->provider,
scanner,
GTK_CSS_PROVIDER_ERROR,
GTK_CSS_PROVIDER_ERROR_NAME,
"'%s' is not a valid property name",
name);
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
g_free (name);
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
return;
}
if (property != NULL && strcmp (name, property->name) != 0)
{
@@ -1241,6 +1488,34 @@ parse_declaration (GtkCssScanner *scanner,
}
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
}
else if (name_is_style_property (name))
{
char *value_str;
warn_if_deprecated (scanner, name);
gtk_css_scanner_push_section (scanner, GTK_CSS_SECTION_VALUE);
value_str = _gtk_css_parser_read_value (scanner->parser);
if (value_str)
{
WidgetPropertyValue *val;
val = widget_property_value_new (name, scanner->section);
val->value = value_str;
gtk_css_ruleset_add_style (ruleset, name, val);
}
else
{
_gtk_css_parser_resync (scanner->parser, TRUE, '}');
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_DECLARATION);
return;
}
gtk_css_scanner_pop_section (scanner, GTK_CSS_SECTION_VALUE);
}
else
@@ -1870,10 +2145,20 @@ compare_properties (gconstpointer a, gconstpointer b, gpointer style)
_gtk_style_property_get_name (GTK_STYLE_PROPERTY (styles[*ub].property)));
}
static int
compare_names (gconstpointer a, gconstpointer b)
{
const WidgetPropertyValue *aa = a;
const WidgetPropertyValue *bb = b;
return strcmp (aa->name, bb->name);
}
static void
gtk_css_ruleset_print (const GtkCssRuleset *ruleset,
GString *str)
{
GList *values, *walk;
WidgetPropertyValue *widget_value;
guint i;
_gtk_css_selector_tree_match_print (ruleset->selector_match, str);
@@ -1903,6 +2188,29 @@ gtk_css_ruleset_print (const GtkCssRuleset *ruleset,
g_free (sorted);
}
if (ruleset->widget_style)
{
values = NULL;
for (widget_value = ruleset->widget_style; widget_value != NULL; widget_value = widget_value->next)
values = g_list_prepend (values, widget_value);
/* so the output is identical for identical selector styles */
values = g_list_sort (values, compare_names);
for (walk = values; walk; walk = walk->next)
{
widget_value = walk->data;
g_string_append (str, " ");
g_string_append (str, widget_value->name);
g_string_append (str, ": ");
g_string_append (str, widget_value->value);
g_string_append (str, ";\n");
}
g_list_free (values);
}
g_string_append (str, "}\n");
}

Some files were not shown because too many files have changed in this diff Show More