Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4269ec3f22 | |||
| e68ed9cac1 | |||
| be20a04e04 | |||
| 92e5536335 | |||
| c2da2f7ecd | |||
| 54bfd380a8 | |||
| f01d695e6c | |||
| 619b2465c1 | |||
| cc18191a8e | |||
| 1f8e7c8aab | |||
| 671daea262 | |||
| 76533513c2 | |||
| 0d3988365b | |||
| 0966636803 | |||
| 7c3b30036e | |||
| 988901294d | |||
| 43b9fc6981 | |||
| 25f670faae | |||
| d0068a036f | |||
| fae014eb45 | |||
| f0ea0be15d | |||
| 9650236b23 | |||
| c0e2d7c62f | |||
| cc072eb7cd | |||
| 613213f597 | |||
| e25c25fcb5 | |||
| 52666d6fe5 | |||
| 56b3669411 | |||
| e3b5b76cdd | |||
| bbb28196e5 | |||
| 72d3a9042c | |||
| f2853ffa8e | |||
| fca2ba963d | |||
| 806779769e | |||
| 82aa0d1f7c | |||
| 72f1d34eca | |||
| c267a75eef | |||
| 83543423e2 | |||
| d0bb72a2aa | |||
| 8cc2a44268 | |||
| 4800dd3f95 | |||
| 2534310ce9 | |||
| 3a4fbc5e50 | |||
| 89a67ac719 | |||
| 21b84b1890 | |||
| 20935f678b | |||
| c41b4130c6 | |||
| f1b010af66 | |||
| ec1133d6e1 | |||
| 8fcf1b78a4 | |||
| 21f9148155 | |||
| d4f0593b37 |
@@ -9,7 +9,6 @@
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
</gresource>
|
||||
<gresource prefix="/listview_colors">
|
||||
<file compressed="true">color.names.txt</file>
|
||||
<file>listview_colors.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/shortcuts">
|
||||
<file>shortcuts.ui</file>
|
||||
@@ -225,7 +226,6 @@
|
||||
<file>listview_minesweeper.c</file>
|
||||
<file>listview_settings.c</file>
|
||||
<file>listview_weather.c</file>
|
||||
<file>listview_words.c</file>
|
||||
<file>list_store.c</file>
|
||||
<file>markup.c</file>
|
||||
<file>modelbutton.c</file>
|
||||
|
||||
@@ -92,7 +92,7 @@ strings_setup_item_full (GtkSignalListItemFactory *factory,
|
||||
gtk_label_set_xalign (GTK_LABEL (title), 0.0);
|
||||
description = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (description), 0.0);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (description), "dim-label");
|
||||
gtk_widget_add_css_class (description, "dim-label");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
<property name="title">Font Explorer</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="reset">
|
||||
<property name="receives-default">1</property>
|
||||
|
||||
@@ -30,7 +30,6 @@ do_headerbar (GtkWidget *do_widget)
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
|
||||
button = gtk_button_new ();
|
||||
icon = g_themed_icon_new ("mail-send-receive-symbolic");
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">500</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
||||
@@ -627,6 +627,23 @@ setup_listitem_cb (GtkListItemFactory *factory,
|
||||
gtk_expression_unref (color_expression);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_selection_listitem_cb (GtkListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *picture;
|
||||
GtkExpression *color_expression, *expression;
|
||||
|
||||
expression = gtk_constant_expression_new (GTK_TYPE_LIST_ITEM, list_item);
|
||||
color_expression = gtk_property_expression_new (GTK_TYPE_LIST_ITEM, expression, "item");
|
||||
|
||||
picture = gtk_picture_new ();
|
||||
gtk_widget_set_size_request (picture, 8, 8);
|
||||
gtk_expression_bind (color_expression, picture, "paintable", NULL);
|
||||
|
||||
gtk_list_item_set_child (list_item, picture);
|
||||
}
|
||||
|
||||
static void
|
||||
set_title (gpointer item,
|
||||
const char *title)
|
||||
@@ -777,6 +794,47 @@ bind_number_item (GtkSignalListItemFactory *factory,
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
static void
|
||||
update_selection_count (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer data)
|
||||
{
|
||||
char *text;
|
||||
text = g_strdup_printf ("%u", g_list_model_get_n_items (model));
|
||||
gtk_label_set_label (GTK_LABEL (data), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
update_selection_average (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
gpointer data)
|
||||
{
|
||||
guint n = g_list_model_get_n_items (model);
|
||||
GdkRGBA c = { 0, 0, 0, 1 };
|
||||
guint i;
|
||||
GtkColor *color;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
color = g_list_model_get_item (model, i);
|
||||
|
||||
c.red += color->color.red;
|
||||
c.green += color->color.green;
|
||||
c.blue += color->color.blue;
|
||||
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
||||
color = gtk_color_new ("", c.red / n, c.green / n, c.blue / n);
|
||||
gtk_picture_set_paintable (GTK_PICTURE (data), GDK_PAINTABLE (color));
|
||||
g_object_unref (color);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
@@ -797,11 +855,26 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
PangoAttrList *attrs;
|
||||
char *string;
|
||||
guint len;
|
||||
GtkWidget *selection_view;
|
||||
GListModel *selection_filter;
|
||||
GListModel *no_selection;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *selection_size_label;
|
||||
GtkWidget *selection_average_picture;
|
||||
GtkWidget *selection_info_toggle;
|
||||
GtkWidget *selection_info_revealer;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/listview_colors/listview_colors.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Colors");
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
@@ -809,14 +882,85 @@ do_listview_colors (GtkWidget *do_widget)
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), box);
|
||||
|
||||
selection_info_revealer = gtk_revealer_new ();
|
||||
gtk_box_append (GTK_BOX (box), selection_info_revealer);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_revealer_set_child (GTK_REVEALER (selection_info_revealer), grid);
|
||||
gtk_widget_set_margin_start (grid, 10);
|
||||
gtk_widget_set_margin_end (grid, 10);
|
||||
gtk_widget_set_margin_top (grid, 10);
|
||||
gtk_widget_set_margin_bottom (grid, 10);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||
|
||||
label = gtk_label_new ("Selection");
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_widget_add_css_class (label, "title-3");
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 5, 1);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Size:"), 0, 2, 1, 1);
|
||||
|
||||
selection_size_label = gtk_label_new ("0");
|
||||
gtk_grid_attach (GTK_GRID (grid), selection_size_label, 1, 2, 1, 1);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), gtk_label_new ("Average:"), 2, 2, 1, 1);
|
||||
|
||||
selection_average_picture = gtk_picture_new ();
|
||||
gtk_widget_set_size_request (selection_average_picture, 32, 32);
|
||||
gtk_grid_attach (GTK_GRID (grid), selection_average_picture, 3, 2, 1, 1);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 4, 2, 1, 1);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_window_set_child (GTK_WINDOW (window), sw);
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), sw, 0, 1, 5, 1);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_selection_listitem_cb), NULL);
|
||||
selection_view = gtk_grid_view_new_with_factory (factory);
|
||||
gtk_widget_add_css_class (selection_view, "compact");
|
||||
gtk_grid_view_set_max_columns (GTK_GRID_VIEW (selection_view), 200);
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), selection_view);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_box_append (GTK_BOX (box), sw);
|
||||
|
||||
gridview = create_color_grid ();
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), gridview);
|
||||
gtk_widget_set_hexpand (sw, TRUE);
|
||||
gtk_widget_set_vexpand (sw, TRUE);
|
||||
model = gtk_grid_view_get_model (GTK_GRID_VIEW (gridview));
|
||||
|
||||
selection_filter = G_LIST_MODEL (gtk_selection_filter_model_new (GTK_SELECTION_MODEL (model)));
|
||||
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_count), selection_size_label);
|
||||
g_signal_connect (selection_filter, "items-changed", G_CALLBACK (update_selection_average), selection_average_picture);
|
||||
|
||||
no_selection = G_LIST_MODEL (gtk_no_selection_new (selection_filter));
|
||||
gtk_grid_view_set_model (GTK_GRID_VIEW (selection_view), no_selection);
|
||||
g_object_unref (selection_filter);
|
||||
g_object_unref (no_selection);
|
||||
|
||||
g_object_get (model, "model", &model, NULL);
|
||||
|
||||
selection_info_toggle = gtk_toggle_button_new ();
|
||||
gtk_button_set_icon_name (GTK_BUTTON (selection_info_toggle), "emblem-important-symbolic");
|
||||
gtk_widget_set_tooltip_text (selection_info_toggle, "Show selection info");
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), selection_info_toggle);
|
||||
|
||||
g_object_bind_property (selection_info_toggle, "active",
|
||||
selection_info_revealer, "reveal-child",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Refill");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (refill),
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
.view.compact > child {
|
||||
padding: 1px;
|
||||
}
|
||||
@@ -174,7 +174,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">go-up-symbolic</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="title" translatable="yes">Minesweeper</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">New Game</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">480</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="search_button">
|
||||
<property name="icon-name">system-search-symbolic</property>
|
||||
|
||||
@@ -194,8 +194,8 @@ create_weather_model (void)
|
||||
}
|
||||
|
||||
static void
|
||||
setup_widget (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
setup_widget (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *box, *child;
|
||||
|
||||
@@ -218,8 +218,8 @@ setup_widget (GtkListItem *list_item,
|
||||
}
|
||||
|
||||
static void
|
||||
bind_widget (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
bind_widget (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *box, *child;
|
||||
GtkWeatherInfo *info;
|
||||
@@ -282,11 +282,12 @@ create_weather_view (void)
|
||||
{
|
||||
GtkWidget *listview;
|
||||
GListModel *model, *selection;
|
||||
GtkListItemFactory *factory;
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
gtk_functions_list_item_factory_new (setup_widget,
|
||||
bind_widget,
|
||||
NULL, NULL));
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_widget), NULL);
|
||||
listview = gtk_list_view_new_with_factory (factory);
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (listview), GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_list_view_set_show_separators (GTK_LIST_VIEW (listview), TRUE);
|
||||
model = create_weather_model ();
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
/* Lists/Words
|
||||
*
|
||||
* This demo shows filtering a long list - of words.
|
||||
*
|
||||
* You should have the file `/usr/share/dict/words` installed for
|
||||
* this demo to work.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *progress;
|
||||
|
||||
const char *factory_text =
|
||||
"<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||
"<interface>\n"
|
||||
" <template class='GtkListItem'>\n"
|
||||
" <property name='child'>\n"
|
||||
" <object class='GtkLabel'>\n"
|
||||
" <property name='ellipsize'>end</property>\n"
|
||||
" <property name='xalign'>0</property>\n"
|
||||
" <binding name='label'>\n"
|
||||
" <lookup name='string' type='GtkStringObject'>\n"
|
||||
" <lookup name='item'>GtkListItem</lookup>\n"
|
||||
" </lookup>\n"
|
||||
" </binding>\n"
|
||||
" </object>\n"
|
||||
" </property>\n"
|
||||
" </template>\n"
|
||||
"</interface>\n";
|
||||
|
||||
static void
|
||||
update_title_cb (GtkFilterListModel *model)
|
||||
{
|
||||
guint total;
|
||||
char *title;
|
||||
guint pending;
|
||||
|
||||
total = g_list_model_get_n_items (gtk_filter_list_model_get_model (model));
|
||||
pending = gtk_filter_list_model_get_pending (model);
|
||||
|
||||
title = g_strdup_printf ("%u lines", g_list_model_get_n_items (G_LIST_MODEL (model)));
|
||||
|
||||
gtk_widget_set_visible (progress, pending != 0);
|
||||
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), (total - pending) / (double) total);
|
||||
gtk_window_set_title (GTK_WINDOW (window), title);
|
||||
g_free (title);
|
||||
}
|
||||
|
||||
static void
|
||||
read_lines_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GBufferedInputStream *stream = G_BUFFERED_INPUT_STREAM (object);
|
||||
GtkStringList *stringlist = data;
|
||||
GError *error = NULL;
|
||||
gsize size;
|
||||
GPtrArray *lines;
|
||||
gssize n_filled;
|
||||
const char *buffer, *newline;
|
||||
|
||||
n_filled = g_buffered_input_stream_fill_finish (stream, result, &error);
|
||||
if (n_filled < 0)
|
||||
{
|
||||
g_print ("Could not read data: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
|
||||
|
||||
if (n_filled == 0)
|
||||
{
|
||||
if (size)
|
||||
gtk_string_list_take (stringlist, g_utf8_make_valid (buffer, size));
|
||||
return;
|
||||
}
|
||||
|
||||
lines = NULL;
|
||||
while ((newline = memchr (buffer, '\n', size)))
|
||||
{
|
||||
if (newline > buffer)
|
||||
{
|
||||
if (lines == NULL)
|
||||
lines = g_ptr_array_new_with_free_func (g_free);
|
||||
g_ptr_array_add (lines, g_utf8_make_valid (buffer, newline - buffer));
|
||||
}
|
||||
if (g_input_stream_skip (G_INPUT_STREAM (stream), newline - buffer + 1, NULL, &error) < 0)
|
||||
{
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
}
|
||||
buffer = g_buffered_input_stream_peek_buffer (stream, &size);
|
||||
}
|
||||
if (lines == NULL)
|
||||
{
|
||||
g_buffered_input_stream_set_buffer_size (stream, g_buffered_input_stream_get_buffer_size (stream) + 4096);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ptr_array_add (lines, NULL);
|
||||
gtk_string_list_splice (stringlist, g_list_model_get_n_items (G_LIST_MODEL (stringlist)), 0, (const char **) lines->pdata);
|
||||
g_ptr_array_free (lines, TRUE);
|
||||
}
|
||||
|
||||
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
|
||||
}
|
||||
|
||||
static void
|
||||
file_is_open_cb (GObject *file,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFileInputStream *file_stream;
|
||||
GBufferedInputStream *stream;
|
||||
|
||||
file_stream = g_file_read_finish (G_FILE (file), result, &error);
|
||||
if (file_stream == NULL)
|
||||
{
|
||||
g_print ("Could not open file: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
stream = G_BUFFERED_INPUT_STREAM (g_buffered_input_stream_new (G_INPUT_STREAM (file_stream)));
|
||||
g_buffered_input_stream_fill_async (stream, -1, G_PRIORITY_HIGH_IDLE, NULL, read_lines_cb, data);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
static void
|
||||
load_file (GtkStringList *list,
|
||||
GFile *file)
|
||||
{
|
||||
gtk_string_list_splice (list, 0, g_list_model_get_n_items (G_LIST_MODEL (list)), NULL);
|
||||
g_file_read_async (file, G_PRIORITY_HIGH_IDLE, NULL, file_is_open_cb, list);
|
||||
}
|
||||
|
||||
static void
|
||||
file_selected_cb (GtkWidget *button,
|
||||
GtkStringList *stringlist)
|
||||
{
|
||||
GFile *file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (button));
|
||||
|
||||
if (file)
|
||||
{
|
||||
load_file (stringlist, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_listview_words (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkWidget *header, *listview, *sw, *vbox, *search_entry, *open_button, *overlay;
|
||||
GtkFilterListModel *filter_model;
|
||||
GtkNoSelection *selection;
|
||||
GtkStringList *stringlist;
|
||||
GtkFilter *filter;
|
||||
GtkExpression *expression;
|
||||
GFile *file;
|
||||
|
||||
file = g_file_new_for_path ("/usr/share/dict/words");
|
||||
if (g_file_query_exists (file, NULL))
|
||||
{
|
||||
stringlist = gtk_string_list_new (NULL);
|
||||
load_file (stringlist, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
char **words;
|
||||
words = g_strsplit ("lorem ipsum dolor sit amet consectetur adipisci elit sed eiusmod tempor incidunt labore et dolore magna aliqua ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat", " ", -1);
|
||||
stringlist = gtk_string_list_new ((const char **) words);
|
||||
g_strfreev (words);
|
||||
}
|
||||
|
||||
filter = gtk_string_filter_new ();
|
||||
expression = gtk_property_expression_new (GTK_TYPE_STRING_OBJECT, NULL, "string");
|
||||
gtk_string_filter_set_expression (GTK_STRING_FILTER (filter), expression);
|
||||
gtk_expression_unref (expression);
|
||||
filter_model = gtk_filter_list_model_new (G_LIST_MODEL (stringlist), filter);
|
||||
gtk_filter_list_model_set_incremental (filter_model, TRUE);
|
||||
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
open_button = gtk_file_chooser_button_new ("_Open", GTK_FILE_CHOOSER_ACTION_OPEN);
|
||||
g_signal_connect (open_button, "file-set", G_CALLBACK (file_selected_cb), stringlist);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), open_button);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer*)&window);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_window_set_child (GTK_WINDOW (window), vbox);
|
||||
|
||||
search_entry = gtk_search_entry_new ();
|
||||
g_object_bind_property (search_entry, "text", filter, "search", 0);
|
||||
gtk_box_append (GTK_BOX (vbox), search_entry);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_box_append (GTK_BOX (vbox), overlay);
|
||||
|
||||
progress = gtk_progress_bar_new ();
|
||||
gtk_widget_set_halign (progress, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (progress, GTK_ALIGN_START);
|
||||
gtk_widget_set_hexpand (progress, TRUE);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), progress);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_overlay_set_child (GTK_OVERLAY (overlay), sw);
|
||||
|
||||
listview = gtk_list_view_new_with_factory (
|
||||
gtk_builder_list_item_factory_new_from_bytes (NULL,
|
||||
g_bytes_new_static (factory_text, strlen (factory_text))));
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), listview);
|
||||
selection = gtk_no_selection_new (G_LIST_MODEL (filter_model));
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (listview), G_LIST_MODEL (selection));
|
||||
g_object_unref (selection);
|
||||
|
||||
g_signal_connect (filter_model, "items-changed", G_CALLBACK (update_title_cb), progress);
|
||||
g_signal_connect (filter_model, "notify::pending", G_CALLBACK (update_title_cb), progress);
|
||||
update_title_cb (filter_model);
|
||||
|
||||
g_object_unref (filter_model);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
<property name="default-height">600</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="valign">center</property>
|
||||
|
||||
@@ -69,7 +69,6 @@ do_markup (GtkWidget *do_widget)
|
||||
g_signal_connect (show_source, "toggled", G_CALLBACK (source_toggled), stack);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), show_source);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@ demos = files([
|
||||
'listview_minesweeper.c',
|
||||
'listview_settings.c',
|
||||
'listview_weather.c',
|
||||
'listview_words.c',
|
||||
'markup.c',
|
||||
'modelbutton.c',
|
||||
'overlay.c',
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
<property name="title" translatable="yes">Model Button</property>
|
||||
<property name="resizable">0</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
</object>
|
||||
<object class="GtkHeaderBar"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
|
||||
@@ -392,7 +392,6 @@ do_paint (GtkWidget *toplevel)
|
||||
gtk_window_set_child (GTK_WINDOW (window), draw_area);
|
||||
|
||||
headerbar = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (headerbar), TRUE);
|
||||
|
||||
colorbutton = gtk_color_button_new ();
|
||||
g_signal_connect (colorbutton, "color-set",
|
||||
|
||||
@@ -276,7 +276,6 @@ do_peg_solitaire (GtkWidget *do_widget)
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (restart), NULL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||
window = gtk_window_new ();
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
|
||||
@@ -40,7 +40,6 @@ do_sidebar (GtkWidget *do_widget)
|
||||
gtk_widget_set_size_request (window, 500, 350);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR(header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW(window), header);
|
||||
gtk_window_set_title (GTK_WINDOW(window), "Stack Sidebar");
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
||||
|
||||
@@ -470,7 +470,6 @@ do_sliding_puzzle (GtkWidget *do_widget)
|
||||
g_signal_connect (restart, "clicked", G_CALLBACK (reshuffle), NULL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), restart);
|
||||
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), tweak);
|
||||
window = gtk_window_new ();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<property name="resizable">0</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkToggleButton" id="toggle">
|
||||
<property name="label">Cycle</property>
|
||||
|
||||
@@ -73,7 +73,6 @@ do_video_player (GtkWidget *do_widget)
|
||||
gtk_window_set_child (GTK_WINDOW (window), video);
|
||||
|
||||
title = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (title), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), title);
|
||||
|
||||
open_button = gtk_button_new_with_mnemonic ("_Open");
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
<property name="focus-widget">text_view</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
|
||||
@@ -436,7 +436,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus.</property>
|
||||
<property name="title">GTK Widget Factory</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar1">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="stack_switcher">
|
||||
<property name="stack">toplevel_stack</property>
|
||||
|
||||
@@ -1423,7 +1423,6 @@ the search bar below the header bar.
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
@@ -1537,7 +1536,6 @@ GtkMenuButton, GtkRevealer and GtkListBox.
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
<xi:include href="xml/gtksingleselection.xml" />
|
||||
<xi:include href="xml/gtkmultiselection.xml" />
|
||||
</section>
|
||||
<xi:include href="xml/gtkselectionfiltermodel.xml" />
|
||||
<xi:include href="xml/gtkbookmarklist.xml" />
|
||||
<xi:include href="xml/gtkdirectorylist.xml" />
|
||||
<xi:include href="xml/gtkstringlist.xml" />
|
||||
|
||||
@@ -348,7 +348,6 @@ GtkBitset
|
||||
gtk_bitset_ref
|
||||
gtk_bitset_unref
|
||||
gtk_bitset_new_empty
|
||||
gtk_bitset_new_range
|
||||
gtk_bitset_copy
|
||||
<SUBSECTION>
|
||||
gtk_bitset_contains
|
||||
@@ -450,6 +449,7 @@ gtk_single_selection_get_type
|
||||
<TITLE>GtkMultiSeledction</TITLE>
|
||||
GtkMultiSelection
|
||||
gtk_multi_selection_new
|
||||
gtk_multi_selection_get_model
|
||||
<SUBSECTION Private>
|
||||
gtk_multi_selection_get_type
|
||||
</SECTION>
|
||||
@@ -1544,9 +1544,6 @@ gtk_filter_list_model_set_model
|
||||
gtk_filter_list_model_get_model
|
||||
gtk_filter_list_model_set_filter
|
||||
gtk_filter_list_model_get_filter
|
||||
gtk_filter_list_model_set_incremental
|
||||
gtk_filter_list_model_get_incremental
|
||||
gtk_filter_list_model_get_pending
|
||||
<SUBSECTION Standard>
|
||||
GTK_FILTER_LIST_MODEL
|
||||
GTK_IS_FILTER_LIST_MODEL
|
||||
@@ -7616,3 +7613,13 @@ gtk_string_list_get_string
|
||||
GtkStringObject
|
||||
gtk_string_object_get_string
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkselectionfiltermodel</FILE>
|
||||
<TITLE>GtkSelectionFilterModel</TITLE>
|
||||
GtkSelectionFilterModel
|
||||
gtk_selection_filter_model_new
|
||||
gtk_selection_filter_model_new_for_type
|
||||
gtk_selection_filter_model_set_model
|
||||
gtk_selection_filter_model_get_model
|
||||
</SECTION>
|
||||
|
||||
@@ -184,6 +184,7 @@ gtk_scrollbar_get_type
|
||||
gtk_scrolled_window_get_type
|
||||
gtk_search_bar_get_type
|
||||
gtk_search_entry_get_type
|
||||
gtk_selection_filter_model_get_type
|
||||
gtk_selection_model_get_type
|
||||
gtk_separator_get_type
|
||||
gtk_settings_get_type
|
||||
|
||||
@@ -411,6 +411,7 @@ and gtk_box_append(). You can also reorder box children as necessary.
|
||||
The gtk_header_bar_set_show_close_button() function has been renamed to
|
||||
the more accurate name gtk_header_bar_set_show_title_buttons(). The
|
||||
corresponding getter and the property itself have also been renamed.
|
||||
The default value of the property is now %TRUE instead of %FALSE.
|
||||
|
||||
The gtk_header_bar_set_custom_title() function has been renamed to
|
||||
the more accurate name gtk_header_bar_set_title_widget(). The
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="lines_label">
|
||||
<property name="visible">0</property>
|
||||
|
||||
@@ -15,7 +15,6 @@ new_window (GApplication *app,
|
||||
gtk_window_set_icon_name (GTK_WINDOW (window), "sunny");
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
|
||||
@@ -1184,7 +1184,7 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
|
||||
if (timings)
|
||||
timings->drawn_time = frame_drawn_time;
|
||||
|
||||
if (surface_impl->toplevel->frame_pending)
|
||||
if (!surface_impl->toplevel->frame_still_painting && surface_impl->toplevel->frame_pending)
|
||||
{
|
||||
surface_impl->toplevel->frame_pending = FALSE;
|
||||
gdk_surface_thaw_updates (win);
|
||||
|
||||
+49
-10
@@ -582,6 +582,23 @@ create_legacy_context (GdkDisplay *display,
|
||||
}
|
||||
|
||||
#ifdef HAVE_XDAMAGE
|
||||
static void
|
||||
finish_frame (GdkGLContext *context)
|
||||
{
|
||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (context_x11->xdamage == 0)
|
||||
return;
|
||||
|
||||
if (context_x11->frame_fence == 0)
|
||||
return;
|
||||
|
||||
glDeleteSync (context_x11->frame_fence);
|
||||
context_x11->frame_fence = 0;
|
||||
_gdk_x11_surface_set_frame_still_painting (surface, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_context_for_frame_fence (GdkGLContext *context)
|
||||
{
|
||||
@@ -628,7 +645,6 @@ on_gl_surface_xevent (GdkGLContext *context,
|
||||
GdkX11Display *display_x11)
|
||||
{
|
||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
XDamageNotifyEvent *damage_xevent;
|
||||
|
||||
if (!context_x11->is_attached)
|
||||
@@ -675,9 +691,7 @@ on_gl_surface_xevent (GdkGLContext *context,
|
||||
case GL_WAIT_FAILED:
|
||||
if (wait_result == GL_WAIT_FAILED)
|
||||
g_warning ("failed to wait on GL fence associated with last swap buffers call");
|
||||
glDeleteSync (context_x11->frame_fence);
|
||||
context_x11->frame_fence = 0;
|
||||
_gdk_x11_surface_set_frame_still_painting (surface, FALSE);
|
||||
finish_frame (context);
|
||||
break;
|
||||
|
||||
/* We assume that if the fence hasn't been signaled, that this
|
||||
@@ -696,6 +710,21 @@ on_gl_surface_xevent (GdkGLContext *context,
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_surface_state_changed (GdkGLContext *context)
|
||||
{
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if ((surface->state & GDK_SURFACE_STATE_WITHDRAWN) == 0)
|
||||
return;
|
||||
|
||||
/* If we're about to withdraw the surface, then we don't care if the frame is
|
||||
* still getting rendered by the GPU. The compositor is going to remove the surface
|
||||
* from the scene anyway, so wrap up the frame.
|
||||
*/
|
||||
finish_frame (context);
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
@@ -878,13 +907,23 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
|
||||
gdk_x11_surface_get_xid (surface),
|
||||
XDamageReportRawRectangles);
|
||||
if (gdk_x11_display_error_trap_pop (display))
|
||||
context_x11->xdamage = 0;
|
||||
{
|
||||
context_x11->xdamage = 0;
|
||||
}
|
||||
else
|
||||
g_signal_connect_object (G_OBJECT (display),
|
||||
"xevent",
|
||||
G_CALLBACK (on_gl_surface_xevent),
|
||||
context,
|
||||
G_CONNECT_SWAPPED);
|
||||
{
|
||||
g_signal_connect_object (G_OBJECT (display),
|
||||
"xevent",
|
||||
G_CALLBACK (on_gl_surface_xevent),
|
||||
context,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (G_OBJECT (surface),
|
||||
"notify::state",
|
||||
G_CALLBACK (on_surface_state_changed),
|
||||
context,
|
||||
G_CONNECT_SWAPPED);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+16
-6
@@ -2241,12 +2241,23 @@ render_cross_fade_node (GskGLRenderer *self,
|
||||
{
|
||||
GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
|
||||
GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
|
||||
float progress = gsk_cross_fade_node_get_progress (node);
|
||||
const float progress = gsk_cross_fade_node_get_progress (node);
|
||||
TextureRegion start_region;
|
||||
TextureRegion end_region;
|
||||
gboolean is_offscreen1, is_offscreen2;
|
||||
OpCrossFade *op;
|
||||
|
||||
if (progress <= 0)
|
||||
{
|
||||
gsk_gl_renderer_add_render_ops (self, start_node, builder);
|
||||
return;
|
||||
}
|
||||
else if (progress >= 1)
|
||||
{
|
||||
gsk_gl_renderer_add_render_ops (self, end_node, builder);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: We create 2 textures here as big as the cross-fade node, but both the
|
||||
* start and the end node might be a lot smaller than that. */
|
||||
|
||||
@@ -2266,11 +2277,10 @@ render_cross_fade_node (GskGLRenderer *self,
|
||||
&end_region, &is_offscreen2,
|
||||
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
|
||||
{
|
||||
load_vertex_data_with_region (ops_draw (builder, NULL),
|
||||
node,
|
||||
builder,
|
||||
&start_region,
|
||||
TRUE);
|
||||
const float prev_opacity = ops_set_opacity (builder, builder->current_opacity * progress);
|
||||
gsk_gl_renderer_add_render_ops (self, start_node, builder);
|
||||
ops_set_opacity (builder, prev_opacity);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+19
-19
@@ -104,7 +104,7 @@ gsk_color_node_peek_color (GskRenderNode *node)
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_color_node_new:
|
||||
* gsk_color_node_new:
|
||||
* @rgba: a #GdkRGBA specifying a color
|
||||
* @bounds: the rectangle to render the color into
|
||||
*
|
||||
@@ -216,7 +216,7 @@ gsk_linear_gradient_node_diff (GskRenderNode *node1,
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gsk_render_node_diff_impossible (node1, node2, region);
|
||||
}
|
||||
|
||||
@@ -1163,7 +1163,7 @@ gsk_inset_shadow_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_inset_shadow_node_new:
|
||||
* gsk_inset_shadow_node_new:
|
||||
* @outline: outline of the region containing the shadow
|
||||
* @color: color of the shadow
|
||||
* @dx: horizontal offset of shadow
|
||||
@@ -1465,7 +1465,7 @@ gsk_outset_shadow_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_outset_shadow_node_new:
|
||||
* gsk_outset_shadow_node_new:
|
||||
* @outline: outline of the region surrounded by shadow
|
||||
* @color: color of the shadow
|
||||
* @dx: horizontal offset of shadow
|
||||
@@ -1672,7 +1672,7 @@ gsk_cairo_node_peek_surface (GskRenderNode *node)
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_cairo_node_new:
|
||||
* gsk_cairo_node_new:
|
||||
* @bounds: the rectangle to render to
|
||||
*
|
||||
* Creates a #GskRenderNode that will render a cairo surface
|
||||
@@ -1982,7 +1982,7 @@ gsk_transform_node_draw (GskRenderNode *node,
|
||||
ctm.xy, ctm.yy,
|
||||
ctm.x0, ctm.y0));
|
||||
cairo_transform (cr, &ctm);
|
||||
|
||||
|
||||
gsk_render_node_draw (self->child, cr);
|
||||
}
|
||||
|
||||
@@ -2062,7 +2062,7 @@ gsk_transform_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_transform_node_new:
|
||||
* gsk_transform_node_new:
|
||||
* @child: The node to transform
|
||||
* @transform: (transfer none): The transform to apply
|
||||
*
|
||||
@@ -2188,7 +2188,7 @@ gsk_opacity_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_opacity_node_new:
|
||||
* gsk_opacity_node_new:
|
||||
* @child: The node to draw
|
||||
* @opacity: The opacity to apply
|
||||
*
|
||||
@@ -2380,7 +2380,7 @@ nope:
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_color_matrix_node_new:
|
||||
* gsk_color_matrix_node_new:
|
||||
* @child: The node to draw
|
||||
* @color_matrix: The matrix to apply
|
||||
* @color_offset: Values to add to the color
|
||||
@@ -2533,7 +2533,7 @@ gsk_repeat_node_draw (GskRenderNode *node,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_repeat_node_new:
|
||||
* gsk_repeat_node_new:
|
||||
* @bounds: The bounds of the area to be painted
|
||||
* @child: The child to repeat
|
||||
* @child_bounds: (allow-none): The area of the child to repeat or %NULL to
|
||||
@@ -2670,7 +2670,7 @@ gsk_clip_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_clip_node_new:
|
||||
* gsk_clip_node_new:
|
||||
* @child: The node to draw
|
||||
* @clip: The clip to apply
|
||||
*
|
||||
@@ -2800,7 +2800,7 @@ gsk_rounded_clip_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_rounded_clip_node_new:
|
||||
* gsk_rounded_clip_node_new:
|
||||
* @child: The node to draw
|
||||
* @clip: The clip to apply
|
||||
*
|
||||
@@ -3013,7 +3013,7 @@ gsk_shadow_node_get_bounds (GskShadowNode *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_shadow_node_new:
|
||||
* gsk_shadow_node_new:
|
||||
* @child: The node to draw
|
||||
* @shadows: (array length=n_shadows): The shadows to apply
|
||||
* @n_shadows: number of entries in the @shadows array
|
||||
@@ -3210,7 +3210,7 @@ gsk_blend_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_blend_node_new:
|
||||
* gsk_blend_node_new:
|
||||
* @bottom: The bottom node to be drawn
|
||||
* @top: The node to be blended onto the @bottom node
|
||||
* @blend_mode: The blend mode to use
|
||||
@@ -3359,7 +3359,7 @@ gsk_cross_fade_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_cross_fade_node_new:
|
||||
* gsk_cross_fade_node_new:
|
||||
* @start: The start node to be drawn
|
||||
* @end: The node to be cross_fadeed onto the @start node
|
||||
* @progress: How far the fade has progressed from start to end. The value will
|
||||
@@ -3549,7 +3549,7 @@ font_has_color_glyphs (const PangoFont *font)
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_text_node_new:
|
||||
* gsk_text_node_new:
|
||||
* @font: the #PangoFont containing the glyphs
|
||||
* @glyphs: the #PangoGlyphString to render
|
||||
* @color: the foreground color to render with
|
||||
@@ -3953,7 +3953,7 @@ gsk_blur_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_blur_node_new:
|
||||
* gsk_blur_node_new:
|
||||
* @child: the child node to blur
|
||||
* @radius: the blur radius
|
||||
*
|
||||
@@ -4076,9 +4076,9 @@ gsk_debug_node_diff (GskRenderNode *node1,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsk_debug_node_new:
|
||||
* gsk_debug_node_new:
|
||||
* @child: The child to add debug info for
|
||||
* @message: (transfer full): The debug message
|
||||
* @message: (transfer full): The debug message
|
||||
*
|
||||
* Creates a #GskRenderNode that will add debug information about
|
||||
* the given @child.
|
||||
|
||||
@@ -295,6 +295,7 @@ gtk_cell_accessible_action_do_action (AtkAction *action,
|
||||
GtkCellAccessible *cell = GTK_CELL_ACCESSIBLE (action);
|
||||
GtkCellAccessibleParent *parent;
|
||||
|
||||
cell = GTK_CELL_ACCESSIBLE (action);
|
||||
if (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell)) == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ static gunichar
|
||||
gtk_password_entry_accessible_get_character_at_offset (AtkText *atk_text,
|
||||
gint offset)
|
||||
{
|
||||
GtkText *text;
|
||||
GtkText *text = get_text_widget (GTK_ACCESSIBLE (atk_text));
|
||||
char *contents, *index;
|
||||
gunichar result;
|
||||
|
||||
|
||||
@@ -133,7 +133,6 @@
|
||||
#include <gtk/gtkfontchooserdialog.h>
|
||||
#include <gtk/gtkfontchooserwidget.h>
|
||||
#include <gtk/gtkframe.h>
|
||||
#include <gtk/gtkfunctionslistitemfactory.h>
|
||||
#include <gtk/gtkgesture.h>
|
||||
#include <gtk/gtkgestureclick.h>
|
||||
#include <gtk/gtkgesturedrag.h>
|
||||
@@ -214,6 +213,7 @@
|
||||
#include <gtk/gtkscrolledwindow.h>
|
||||
#include <gtk/gtksearchbar.h>
|
||||
#include <gtk/gtksearchentry.h>
|
||||
#include <gtk/gtkselectionfiltermodel.h>
|
||||
#include <gtk/gtkselectionmodel.h>
|
||||
#include <gtk/gtkseparator.h>
|
||||
#include <gtk/gtksettings.h>
|
||||
|
||||
+1
-23
@@ -268,7 +268,7 @@ gtk_bitset_get_nth (const GtkBitset *self,
|
||||
*
|
||||
* Creates a new empty bitset.
|
||||
*
|
||||
* Returns: A new empty bitset
|
||||
* Returns: A new empty bitset.
|
||||
**/
|
||||
GtkBitset *
|
||||
gtk_bitset_new_empty (void)
|
||||
@@ -284,28 +284,6 @@ gtk_bitset_new_empty (void)
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_bitset_new_range:
|
||||
* @start: first value to add
|
||||
* @n_items: number of consecutive values to add
|
||||
*
|
||||
* Creates a bitset with the given range set.
|
||||
*
|
||||
* Returns: A new bitset
|
||||
**/
|
||||
GtkBitset *
|
||||
gtk_bitset_new_range (guint start,
|
||||
guint n_items)
|
||||
{
|
||||
GtkBitset *self;
|
||||
|
||||
self = gtk_bitset_new_empty ();
|
||||
|
||||
gtk_bitset_add_range (self, start, n_items);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_bitset_copy:
|
||||
* @self: a #GtkBitset
|
||||
|
||||
@@ -65,9 +65,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
GtkBitset * gtk_bitset_new_empty (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkBitset * gtk_bitset_copy (const GtkBitset *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkBitset * gtk_bitset_new_range (guint start,
|
||||
guint n_items);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_bitset_remove_all (GtkBitset *self);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
/**
|
||||
* SECTION:gtkbuilderlistitemfactory
|
||||
* @Tiitle: GtkBuilderListItemFactory
|
||||
* @Title: GtkBuilderListItemFactory
|
||||
* @Short_description: A listitem factory using ui files
|
||||
*
|
||||
* #GtkBuilderListItemFactory is a #GtkListItemFactory that creates
|
||||
|
||||
+2
-2
@@ -940,7 +940,7 @@ header_drag_end (GtkGestureDrag *gesture,
|
||||
|
||||
column = g_list_model_get_item (G_LIST_MODEL (self->columns), self->drag_pos);
|
||||
header = gtk_column_view_column_get_header (column);
|
||||
gtk_style_context_remove_class (gtk_widget_get_style_context (header), "dnd");
|
||||
gtk_widget_remove_css_class (header, "dnd");
|
||||
|
||||
sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
|
||||
if (!gtk_gesture_handles_sequence (GTK_GESTURE (gesture), sequence))
|
||||
@@ -1027,7 +1027,7 @@ header_drag_update (GtkGestureDrag *gesture,
|
||||
header = gtk_column_view_column_get_header (column);
|
||||
|
||||
gtk_widget_insert_after (header, self->header, gtk_widget_get_last_child (self->header));
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (header), "dnd");
|
||||
gtk_widget_add_css_class (header, "dnd");
|
||||
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
if (!gtk_widget_has_focus (GTK_WIDGET (self)))
|
||||
|
||||
+1
-1
@@ -943,7 +943,7 @@ gtk_drop_down_set_from_strings (GtkDropDown *self,
|
||||
|
||||
set_default_factory (self);
|
||||
|
||||
model = G_LIST_MODEL (gtk_string_list_new (texts));
|
||||
model = G_LIST_MODEL (gtk_string_list_new ((const char **)texts));
|
||||
gtk_drop_down_set_model (self, model);
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
+44
-11
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
@@ -28,18 +29,50 @@
|
||||
* @Short_description: Expressions to values
|
||||
* @Title: GtkExpression
|
||||
*
|
||||
* GtkExpression provides a way to describe references to #GValues.
|
||||
* GtkExpression provides a way to describe references to values.
|
||||
*
|
||||
* An expression needs to be "evaluated" to obtain the value that it currently refers
|
||||
* to. An evaluation always happens in the context of a current object called `this`
|
||||
* (it mirrors the behavior of object-oriented languages), which may or may not
|
||||
* influence the result of the evaluation. Use gtk_expression_evaluate() for
|
||||
* evaluating an expression.
|
||||
* An important aspect of expressions is that the value can be obtained
|
||||
* from a source that is several steps away. For example, an expression
|
||||
* may describe ‘the value of property A of @object1, which is itself the
|
||||
* value of a property of @object2’. And @object1 may not even exist yet
|
||||
* at the time that the expression is created. This is contrast to GObject
|
||||
* property bindings, which can only create direct connections between
|
||||
* the properties of two objects that must both exist for the duration
|
||||
* of the binding.
|
||||
*
|
||||
* An expression needs to be "evaluated" to obtain the value that it currently
|
||||
* refers to. An evaluation always happens in the context of a current object
|
||||
* called `this` (it mirrors the behavior of object-oriented languages),
|
||||
* which may or may not influence the result of the evaluation. Use
|
||||
* gtk_expression_evaluate() for evaluating an expression.
|
||||
*
|
||||
* Various methods for defining expressions exist, from simple constants via
|
||||
* gtk_constant_expression_new() to looking up properties in a #GObject (even
|
||||
* recursively) via gtk_property_expression_new() or providing custom functions to
|
||||
* transform and combine expressions via gtk_closure_expression_new().
|
||||
* recursively) via gtk_property_expression_new() or providing custom functions
|
||||
* to transform and combine expressions via gtk_closure_expression_new().
|
||||
*
|
||||
* Here is an example of a complex expression:
|
||||
* |[
|
||||
* color_expr = gtk_property_expression_new (GTK_TYPE_LIST_ITEM,
|
||||
* NULL, "item");
|
||||
* expression = gtk_property_expression_new (GTK_TYPE_COLOR,
|
||||
* color_expr,
|
||||
* "name");
|
||||
* ]|
|
||||
* when evaluated with `this` being a GtkListItem, it will obtain the
|
||||
* "item" property from the GtkListItem, and then obtain the "name" property
|
||||
* from the resulting object (which is assumed to be of type GTK_TYPE_COLOR).
|
||||
*
|
||||
* A more concise way to describe this would be
|
||||
* |[
|
||||
* this->item->name
|
||||
* ]|
|
||||
*
|
||||
* The most likely place where you will encounter expressions is in the context
|
||||
* of list models and list widgets using them. For example, #GtkDropDown is
|
||||
* evaluating a GtkExpression to obtain strings from the items in its model
|
||||
* that it can then use to match against the contents of its search entry.
|
||||
* #GtkStringFilter is using a GtkExpression for a similar reason.
|
||||
*
|
||||
* By default, expressions are not paying attention to changes and evaluation is
|
||||
* just a snapshot of the current state at a given time. To get informed about
|
||||
@@ -1537,12 +1570,12 @@ GTK_DEFINE_EXPRESSION_TYPE (GtkCClosureExpression,
|
||||
/**
|
||||
* gtk_cclosure_expression_new:
|
||||
* @value_type: the type of the value that this expression evaluates to
|
||||
* @marshal: (scope call): marshaller used for creating a closure
|
||||
* @marshal: (scope call) (nullable): marshaller used for creating a closure
|
||||
* @n_params: the number of params needed for evaluating @closure
|
||||
* @params: (array length=n_params) (transfer full): expressions for each parameter
|
||||
* @callback_func: (scope notified) (closure user_data) (destroy user_destroy): callback used for creating a closure
|
||||
* @user_data: user data used for creating a closure
|
||||
* @user_destroy: destroy notify for @user_data
|
||||
* @user_data: (nullable): user data used for creating a closure
|
||||
* @user_destroy: (nullable): destroy notify for @user_data
|
||||
*
|
||||
* This function is a variant of gtk_closure_expression_new() that
|
||||
* creates a #GClosure by calling gtk_cclosure_new() with the given
|
||||
|
||||
+92
-4
@@ -73,6 +73,7 @@
|
||||
#include "gtkbuilderprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkfilter.h"
|
||||
|
||||
typedef struct _GtkFileFilterClass GtkFileFilterClass;
|
||||
typedef struct _FilterRule FilterRule;
|
||||
@@ -90,12 +91,12 @@ typedef enum {
|
||||
|
||||
struct _GtkFileFilterClass
|
||||
{
|
||||
GInitiallyUnownedClass parent_class;
|
||||
GtkFilterClass parent_class;
|
||||
};
|
||||
|
||||
struct _GtkFileFilter
|
||||
{
|
||||
GInitiallyUnowned parent_instance;
|
||||
GtkFilter parent_instance;
|
||||
|
||||
gchar *name;
|
||||
GSList *rules;
|
||||
@@ -107,7 +108,7 @@ struct _FilterRule
|
||||
{
|
||||
FilterRuleType type;
|
||||
GtkFileFilterFlags needed;
|
||||
|
||||
|
||||
union {
|
||||
gchar *pattern;
|
||||
gchar *mime_type;
|
||||
@@ -156,7 +157,12 @@ static void gtk_file_filter_buildable_custom_tag_end (GtkBuildable
|
||||
const gchar *tagname,
|
||||
gpointer data);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkFileFilter, gtk_file_filter, G_TYPE_INITIALLY_UNOWNED,
|
||||
static gboolean gtk_file_filter_match (GtkFilter *filter,
|
||||
gpointer item);
|
||||
static GtkFilterMatch gtk_file_filter_get_strictness (GtkFilter *filter);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkFileFilter, gtk_file_filter, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
|
||||
gtk_file_filter_buildable_init))
|
||||
|
||||
@@ -169,11 +175,15 @@ static void
|
||||
gtk_file_filter_class_init (GtkFileFilterClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
GtkFilterClass *filter_class = GTK_FILTER_CLASS (class);
|
||||
|
||||
gobject_class->set_property = gtk_file_filter_set_property;
|
||||
gobject_class->get_property = gtk_file_filter_get_property;
|
||||
gobject_class->finalize = gtk_file_filter_finalize;
|
||||
|
||||
filter_class->match = gtk_file_filter_match;
|
||||
filter_class->get_strictness = gtk_file_filter_get_strictness;
|
||||
|
||||
/**
|
||||
* GtkFileFilter:name:
|
||||
*
|
||||
@@ -436,6 +446,84 @@ gtk_file_filter_buildable_custom_tag_end (GtkBuildable *buildable,
|
||||
}
|
||||
}
|
||||
|
||||
/* GtkFilter implementation */
|
||||
|
||||
static gboolean
|
||||
gtk_file_filter_match (GtkFilter *filter,
|
||||
gpointer item)
|
||||
{
|
||||
GtkFileFilter *file_filter = GTK_FILE_FILTER (filter);
|
||||
GFileInfo *info;
|
||||
GFile *file;
|
||||
GtkFileFilterInfo filter_info = { 0, };
|
||||
GtkFileFilterFlags required;
|
||||
gboolean result;
|
||||
char *mime_type = NULL;
|
||||
char *filename = NULL;
|
||||
char *uri = NULL;
|
||||
|
||||
if (!G_IS_FILE_INFO (item))
|
||||
return TRUE;
|
||||
|
||||
info = G_FILE_INFO (item);
|
||||
file = G_FILE (g_file_info_get_attribute_object (info, "standard::file"));
|
||||
|
||||
required = file_filter->needed;
|
||||
|
||||
filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME;
|
||||
filter_info.display_name = g_file_info_get_display_name (info);
|
||||
|
||||
if (required & GTK_FILE_FILTER_MIME_TYPE)
|
||||
{
|
||||
const char *s = g_file_info_get_content_type (info);
|
||||
if (!s)
|
||||
s = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
|
||||
|
||||
if (s)
|
||||
{
|
||||
mime_type = g_content_type_get_mime_type (s);
|
||||
if (mime_type)
|
||||
{
|
||||
filter_info.mime_type = mime_type;
|
||||
filter_info.contains |= GTK_FILE_FILTER_MIME_TYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (required & GTK_FILE_FILTER_FILENAME)
|
||||
{
|
||||
filename = g_file_get_path (file);
|
||||
if (filename)
|
||||
{
|
||||
filter_info.filename = filename;
|
||||
filter_info.contains |= GTK_FILE_FILTER_FILENAME;
|
||||
}
|
||||
}
|
||||
|
||||
if (required & GTK_FILE_FILTER_URI)
|
||||
{
|
||||
uri = g_file_get_uri (file);
|
||||
if (uri)
|
||||
{
|
||||
filter_info.uri = uri;
|
||||
filter_info.contains |= GTK_FILE_FILTER_URI;
|
||||
}
|
||||
}
|
||||
|
||||
result = gtk_file_filter_filter (file_filter, &filter_info);
|
||||
|
||||
g_free (mime_type);
|
||||
g_free (filename);
|
||||
g_free (uri);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GtkFilterMatch
|
||||
gtk_file_filter_get_strictness (GtkFilter *filter)
|
||||
{
|
||||
return GTK_FILTER_MATCH_SOME;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_file_filter_new:
|
||||
|
||||
+354
-330
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "gtkfilterlistmodel.h"
|
||||
|
||||
#include "gtkbitset.h"
|
||||
#include "gtkrbtreeprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
@@ -35,22 +35,30 @@
|
||||
* listmodel.
|
||||
* It hides some elements from the other model according to
|
||||
* criteria given by a #GtkFilter.
|
||||
*
|
||||
* The model can be set up to do incremental searching, so that
|
||||
* filtering long lists doesn't block the UI. See
|
||||
* gtk_filter_list_model_set_incremental() for details.
|
||||
*/
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_FILTER,
|
||||
PROP_INCREMENTAL,
|
||||
PROP_ITEM_TYPE,
|
||||
PROP_MODEL,
|
||||
PROP_PENDING,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
typedef struct _FilterNode FilterNode;
|
||||
typedef struct _FilterAugment FilterAugment;
|
||||
|
||||
struct _FilterNode
|
||||
{
|
||||
guint visible : 1;
|
||||
};
|
||||
|
||||
struct _FilterAugment
|
||||
{
|
||||
guint n_items;
|
||||
guint n_visible;
|
||||
};
|
||||
|
||||
struct _GtkFilterListModel
|
||||
{
|
||||
GObject parent_instance;
|
||||
@@ -59,11 +67,8 @@ struct _GtkFilterListModel
|
||||
GListModel *model;
|
||||
GtkFilter *filter;
|
||||
GtkFilterMatch strictness;
|
||||
gboolean incremental;
|
||||
|
||||
GtkBitset *matches; /* NULL if strictness != GTK_FILTER_MATCH_SOME */
|
||||
GtkBitset *pending; /* not yet filtered items or NULL if all filtered */
|
||||
guint pending_cb; /* idle callback handle */
|
||||
GtkRbTree *items; /* NULL if strictness != GTK_FILTER_MATCH_SOME */
|
||||
};
|
||||
|
||||
struct _GtkFilterListModelClass
|
||||
@@ -73,6 +78,119 @@ struct _GtkFilterListModelClass
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
static void
|
||||
gtk_filter_list_model_augment (GtkRbTree *filter,
|
||||
gpointer _aug,
|
||||
gpointer _node,
|
||||
gpointer left,
|
||||
gpointer right)
|
||||
{
|
||||
FilterNode *node = _node;
|
||||
FilterAugment *aug = _aug;
|
||||
|
||||
aug->n_items = 1;
|
||||
aug->n_visible = node->visible ? 1 : 0;
|
||||
|
||||
if (left)
|
||||
{
|
||||
FilterAugment *left_aug = gtk_rb_tree_get_augment (filter, left);
|
||||
aug->n_items += left_aug->n_items;
|
||||
aug->n_visible += left_aug->n_visible;
|
||||
}
|
||||
if (right)
|
||||
{
|
||||
FilterAugment *right_aug = gtk_rb_tree_get_augment (filter, right);
|
||||
aug->n_items += right_aug->n_items;
|
||||
aug->n_visible += right_aug->n_visible;
|
||||
}
|
||||
}
|
||||
|
||||
static FilterNode *
|
||||
gtk_filter_list_model_get_nth_filtered (GtkRbTree *tree,
|
||||
guint position,
|
||||
guint *out_unfiltered)
|
||||
{
|
||||
FilterNode *node, *tmp;
|
||||
guint unfiltered;
|
||||
|
||||
node = gtk_rb_tree_get_root (tree);
|
||||
unfiltered = 0;
|
||||
|
||||
while (node)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (node);
|
||||
if (tmp)
|
||||
{
|
||||
FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
|
||||
if (position < aug->n_visible)
|
||||
{
|
||||
node = tmp;
|
||||
continue;
|
||||
}
|
||||
position -= aug->n_visible;
|
||||
unfiltered += aug->n_items;
|
||||
}
|
||||
|
||||
if (node->visible)
|
||||
{
|
||||
if (position == 0)
|
||||
break;
|
||||
position--;
|
||||
}
|
||||
|
||||
unfiltered++;
|
||||
|
||||
node = gtk_rb_tree_node_get_right (node);
|
||||
}
|
||||
|
||||
if (out_unfiltered)
|
||||
*out_unfiltered = unfiltered;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static FilterNode *
|
||||
gtk_filter_list_model_get_nth (GtkRbTree *tree,
|
||||
guint position,
|
||||
guint *out_filtered)
|
||||
{
|
||||
FilterNode *node, *tmp;
|
||||
guint filtered;
|
||||
|
||||
node = gtk_rb_tree_get_root (tree);
|
||||
filtered = 0;
|
||||
|
||||
while (node)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (node);
|
||||
if (tmp)
|
||||
{
|
||||
FilterAugment *aug = gtk_rb_tree_get_augment (tree, tmp);
|
||||
if (position < aug->n_items)
|
||||
{
|
||||
node = tmp;
|
||||
continue;
|
||||
}
|
||||
position -= aug->n_items;
|
||||
filtered += aug->n_visible;
|
||||
}
|
||||
|
||||
if (position == 0)
|
||||
break;
|
||||
|
||||
position--;
|
||||
if (node->visible)
|
||||
filtered++;
|
||||
|
||||
node = gtk_rb_tree_node_get_right (node);
|
||||
}
|
||||
|
||||
if (out_filtered)
|
||||
*out_filtered = filtered;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static GType
|
||||
gtk_filter_list_model_get_item_type (GListModel *list)
|
||||
{
|
||||
@@ -85,6 +203,8 @@ static guint
|
||||
gtk_filter_list_model_get_n_items (GListModel *list)
|
||||
{
|
||||
GtkFilterListModel *self = GTK_FILTER_LIST_MODEL (list);
|
||||
FilterAugment *aug;
|
||||
FilterNode *node;
|
||||
|
||||
switch (self->strictness)
|
||||
{
|
||||
@@ -95,12 +215,18 @@ gtk_filter_list_model_get_n_items (GListModel *list)
|
||||
return g_list_model_get_n_items (self->model);
|
||||
|
||||
case GTK_FILTER_MATCH_SOME:
|
||||
return gtk_bitset_get_size (self->matches);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = gtk_rb_tree_get_root (self->items);
|
||||
if (node == NULL)
|
||||
return 0;
|
||||
|
||||
aug = gtk_rb_tree_get_augment (self->items, node);
|
||||
return aug->n_visible;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
@@ -120,9 +246,7 @@ gtk_filter_list_model_get_item (GListModel *list,
|
||||
break;
|
||||
|
||||
case GTK_FILTER_MATCH_SOME:
|
||||
unfiltered = gtk_bitset_get_nth (self->matches, position);
|
||||
if (unfiltered == 0 && position >= gtk_bitset_get_size (self->matches))
|
||||
return NULL;
|
||||
gtk_filter_list_model_get_nth_filtered (self->items, position, &unfiltered);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -144,8 +268,8 @@ G_DEFINE_TYPE_WITH_CODE (GtkFilterListModel, gtk_filter_list_model, G_TYPE_OBJEC
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_filter_list_model_model_init))
|
||||
|
||||
static gboolean
|
||||
gtk_filter_list_model_run_filter_on_item (GtkFilterListModel *self,
|
||||
guint position)
|
||||
gtk_filter_list_model_run_filter (GtkFilterListModel *self,
|
||||
guint position)
|
||||
{
|
||||
gpointer item;
|
||||
gboolean visible;
|
||||
@@ -160,120 +284,26 @@ gtk_filter_list_model_run_filter_on_item (GtkFilterListModel *self,
|
||||
return visible;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_filter_list_model_run_filter (GtkFilterListModel *self,
|
||||
guint n_steps)
|
||||
static guint
|
||||
gtk_filter_list_model_add_items (GtkFilterListModel *self,
|
||||
FilterNode *after,
|
||||
guint position,
|
||||
guint n_items)
|
||||
{
|
||||
GtkBitsetIter iter;
|
||||
guint i, pos;
|
||||
gboolean more;
|
||||
FilterNode *node;
|
||||
guint i, n_visible;
|
||||
|
||||
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
|
||||
n_visible = 0;
|
||||
|
||||
if (self->pending == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0, more = gtk_bitset_iter_init_first (&iter, self->pending, &pos);
|
||||
i < n_steps && more;
|
||||
i++, more = gtk_bitset_iter_next (&iter, &pos))
|
||||
for (i = 0; i < n_items; i++)
|
||||
{
|
||||
if (gtk_filter_list_model_run_filter_on_item (self, pos))
|
||||
gtk_bitset_add (self->matches, pos);
|
||||
node = gtk_rb_tree_insert_before (self->items, after);
|
||||
node->visible = gtk_filter_list_model_run_filter (self, position + i);
|
||||
if (node->visible)
|
||||
n_visible++;
|
||||
}
|
||||
|
||||
if (more)
|
||||
gtk_bitset_remove_range_closed (self->pending, 0, pos);
|
||||
else
|
||||
g_clear_pointer (&self->pending, gtk_bitset_unref);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_filter_list_model_stop_filtering (GtkFilterListModel *self)
|
||||
{
|
||||
gboolean notify_pending = self->pending != NULL;
|
||||
|
||||
g_clear_pointer (&self->pending, gtk_bitset_unref);
|
||||
g_clear_handle_id (&self->pending_cb, g_source_remove);
|
||||
|
||||
if (notify_pending)
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_filter_list_model_emit_items_changed_for_changes (GtkFilterListModel *self,
|
||||
GtkBitset *old)
|
||||
{
|
||||
GtkBitset *changes;
|
||||
|
||||
changes = gtk_bitset_copy (self->matches);
|
||||
gtk_bitset_difference (changes, old);
|
||||
if (!gtk_bitset_is_empty (changes))
|
||||
{
|
||||
guint min, max;
|
||||
|
||||
min = gtk_bitset_get_minimum (changes);
|
||||
max = gtk_bitset_get_maximum (changes);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self),
|
||||
min > 0 ? gtk_bitset_get_size_in_range (self->matches, 0, min - 1) : 0,
|
||||
gtk_bitset_get_size_in_range (old, min, max),
|
||||
gtk_bitset_get_size_in_range (self->matches, min, max));
|
||||
}
|
||||
gtk_bitset_unref (changes);
|
||||
gtk_bitset_unref (old);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_filter_list_model_run_filter_cb (gpointer data)
|
||||
{
|
||||
GtkFilterListModel *self = data;
|
||||
GtkBitset *old;
|
||||
|
||||
old = gtk_bitset_copy (self->matches);
|
||||
gtk_filter_list_model_run_filter (self, 512);
|
||||
|
||||
if (self->pending == NULL)
|
||||
gtk_filter_list_model_stop_filtering (self);
|
||||
|
||||
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
/* NB: bitset is (transfer full) */
|
||||
static void
|
||||
gtk_filter_list_model_start_filtering (GtkFilterListModel *self,
|
||||
GtkBitset *items)
|
||||
{
|
||||
if (self->pending)
|
||||
{
|
||||
gtk_bitset_union (self->pending, items);
|
||||
gtk_bitset_unref (items);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gtk_bitset_is_empty (items))
|
||||
{
|
||||
gtk_bitset_unref (items);
|
||||
return;
|
||||
}
|
||||
|
||||
self->pending = items;
|
||||
|
||||
if (!self->incremental)
|
||||
{
|
||||
gtk_filter_list_model_run_filter (self, G_MAXUINT);
|
||||
g_assert (self->pending == NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PENDING]);
|
||||
g_assert (self->pending_cb == 0);
|
||||
self->pending_cb = g_idle_add (gtk_filter_list_model_run_filter_cb, self);
|
||||
g_source_set_name_by_id (self->pending_cb, "[gtk] gtk_filter_list_model_run_filter_cb");
|
||||
return n_visible;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -283,7 +313,8 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
|
||||
guint added,
|
||||
GtkFilterListModel *self)
|
||||
{
|
||||
guint filter_removed, filter_added;
|
||||
FilterNode *node;
|
||||
guint i, filter_position, filter_removed, filter_added;
|
||||
|
||||
switch (self->strictness)
|
||||
{
|
||||
@@ -301,22 +332,22 @@ gtk_filter_list_model_items_changed_cb (GListModel *model,
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (removed > 0)
|
||||
filter_removed = gtk_bitset_get_size_in_range (self->matches, position, position + removed - 1);
|
||||
else
|
||||
filter_removed = 0;
|
||||
node = gtk_filter_list_model_get_nth (self->items, position, &filter_position);
|
||||
|
||||
gtk_bitset_slice (self->matches, position, removed, added);
|
||||
if (self->pending)
|
||||
gtk_bitset_slice (self->pending, position, removed, added);
|
||||
filter_removed = 0;
|
||||
for (i = 0; i < removed; i++)
|
||||
{
|
||||
FilterNode *next = gtk_rb_tree_node_get_next (node);
|
||||
if (node->visible)
|
||||
filter_removed++;
|
||||
gtk_rb_tree_remove (self->items, node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
gtk_filter_list_model_start_filtering (self, gtk_bitset_new_range (position, added));
|
||||
filter_added = gtk_bitset_get_size_in_range (self->matches, position, position + added - 1);
|
||||
filter_added = gtk_filter_list_model_add_items (self, node, position, added);
|
||||
|
||||
if (filter_removed > 0 || filter_added > 0)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self),
|
||||
gtk_bitset_get_size_in_range (self->matches, 0, position),
|
||||
filter_removed, filter_added);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), filter_position, filter_removed, filter_added);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -333,10 +364,6 @@ gtk_filter_list_model_set_property (GObject *object,
|
||||
gtk_filter_list_model_set_filter (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_INCREMENTAL:
|
||||
gtk_filter_list_model_set_incremental (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_ITEM_TYPE:
|
||||
self->item_type = g_value_get_gtype (value);
|
||||
break;
|
||||
@@ -365,10 +392,6 @@ gtk_filter_list_model_get_property (GObject *object,
|
||||
g_value_set_object (value, self->filter);
|
||||
break;
|
||||
|
||||
case PROP_INCREMENTAL:
|
||||
g_value_set_boolean (value, self->incremental);
|
||||
break;
|
||||
|
||||
case PROP_ITEM_TYPE:
|
||||
g_value_set_gtype (value, self->item_type);
|
||||
break;
|
||||
@@ -377,10 +400,6 @@ gtk_filter_list_model_get_property (GObject *object,
|
||||
g_value_set_object (value, self->model);
|
||||
break;
|
||||
|
||||
case PROP_PENDING:
|
||||
g_value_set_uint (value, gtk_filter_list_model_get_pending (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -393,16 +412,109 @@ gtk_filter_list_model_clear_model (GtkFilterListModel *self)
|
||||
if (self->model == NULL)
|
||||
return;
|
||||
|
||||
gtk_filter_list_model_stop_filtering (self);
|
||||
g_signal_handlers_disconnect_by_func (self->model, gtk_filter_list_model_items_changed_cb, self);
|
||||
g_clear_object (&self->model);
|
||||
if (self->matches)
|
||||
gtk_bitset_remove_all (self->matches);
|
||||
if (self->items)
|
||||
gtk_rb_tree_remove_all (self->items);
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gtk_filter_list_model_find_filtered:
|
||||
* @self: a #GtkFilterListModel
|
||||
* @start: (out) (caller-allocates): number of unfiltered items
|
||||
* at start of list
|
||||
* @end: (out) (caller-allocates): number of unfiltered items
|
||||
* at end of list
|
||||
* @n_items: (out) (caller-allocates): number of unfiltered items in
|
||||
* list
|
||||
*
|
||||
* Checks if elements in self->items are filtered out and returns
|
||||
* the range that they occupy.
|
||||
* This function is intended to be used for GListModel::items-changed
|
||||
* emissions, so it is called in an intermediate state for @self.
|
||||
*
|
||||
* Returns: %TRUE if elements are filtered out, %FALSE if none are
|
||||
**/
|
||||
static gboolean
|
||||
gtk_filter_list_model_find_filtered (GtkFilterListModel *self,
|
||||
guint *start,
|
||||
guint *end,
|
||||
guint *n_items)
|
||||
{
|
||||
FilterNode *root, *node, *tmp;
|
||||
FilterAugment *aug;
|
||||
|
||||
if (self->items == NULL || self->model == NULL)
|
||||
return FALSE;
|
||||
|
||||
root = gtk_rb_tree_get_root (self->items);
|
||||
if (root == NULL)
|
||||
return FALSE; /* empty parent model */
|
||||
|
||||
aug = gtk_rb_tree_get_augment (self->items, root);
|
||||
if (aug->n_items == aug->n_visible)
|
||||
return FALSE; /* all items visible */
|
||||
|
||||
/* find first filtered */
|
||||
*start = 0;
|
||||
*end = 0;
|
||||
*n_items = aug->n_visible;
|
||||
|
||||
node = root;
|
||||
while (node)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_left (node);
|
||||
if (tmp)
|
||||
{
|
||||
aug = gtk_rb_tree_get_augment (self->items, tmp);
|
||||
if (aug->n_visible < aug->n_items)
|
||||
{
|
||||
node = tmp;
|
||||
continue;
|
||||
}
|
||||
*start += aug->n_items;
|
||||
}
|
||||
|
||||
if (!node->visible)
|
||||
break;
|
||||
|
||||
(*start)++;
|
||||
|
||||
node = gtk_rb_tree_node_get_right (node);
|
||||
}
|
||||
|
||||
/* find last filtered by doing everything the opposite way */
|
||||
node = root;
|
||||
while (node)
|
||||
{
|
||||
tmp = gtk_rb_tree_node_get_right (node);
|
||||
if (tmp)
|
||||
{
|
||||
aug = gtk_rb_tree_get_augment (self->items, tmp);
|
||||
if (aug->n_visible < aug->n_items)
|
||||
{
|
||||
node = tmp;
|
||||
continue;
|
||||
}
|
||||
*end += aug->n_items;
|
||||
}
|
||||
|
||||
if (!node->visible)
|
||||
break;
|
||||
|
||||
(*end)++;
|
||||
|
||||
node = gtk_rb_tree_node_get_left (node);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_filter_list_model_refilter (GtkFilterListModel *self,
|
||||
GtkFilterChange change)
|
||||
gtk_filter_list_model_refilter (GtkFilterListModel *self);
|
||||
|
||||
static void
|
||||
gtk_filter_list_model_update_strictness_and_refilter (GtkFilterListModel *self)
|
||||
{
|
||||
GtkFilterMatch new_strictness;
|
||||
|
||||
@@ -420,9 +532,8 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
|
||||
case GTK_FILTER_MATCH_NONE:
|
||||
{
|
||||
guint n_before = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
||||
self->strictness = new_strictness;
|
||||
gtk_filter_list_model_stop_filtering (self);
|
||||
if (n_before > 0)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_before, 0);
|
||||
}
|
||||
@@ -442,35 +553,16 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
|
||||
case GTK_FILTER_MATCH_SOME:
|
||||
{
|
||||
guint start, end, n_before, n_after;
|
||||
|
||||
gtk_filter_list_model_stop_filtering (self);
|
||||
self->strictness = new_strictness;
|
||||
n_after = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
start = gtk_bitset_get_minimum (self->matches);
|
||||
end = gtk_bitset_get_maximum (self->matches);
|
||||
|
||||
n_before = gtk_bitset_get_size (self->matches);
|
||||
if (n_before == n_after)
|
||||
if (gtk_filter_list_model_find_filtered (self, &start, &end, &n_before))
|
||||
{
|
||||
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||
n_after = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkBitset *inverse;
|
||||
|
||||
inverse = gtk_bitset_new_range (0, n_after);
|
||||
gtk_bitset_subtract (inverse, self->matches);
|
||||
/* otherwise all items would be visible */
|
||||
g_assert (!gtk_bitset_is_empty (inverse));
|
||||
|
||||
/* find first filtered */
|
||||
start = gtk_bitset_get_minimum (inverse);
|
||||
end = n_after - gtk_bitset_get_maximum (inverse) - 1;
|
||||
|
||||
gtk_bitset_unref (inverse);
|
||||
|
||||
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
|
||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -482,44 +574,40 @@ gtk_filter_list_model_refilter (GtkFilterListModel *self,
|
||||
break;
|
||||
|
||||
case GTK_FILTER_MATCH_SOME:
|
||||
{
|
||||
GtkBitset *old, *pending;
|
||||
|
||||
if (self->matches == NULL)
|
||||
switch (self->strictness)
|
||||
{
|
||||
case GTK_FILTER_MATCH_NONE:
|
||||
{
|
||||
if (self->strictness == GTK_FILTER_MATCH_ALL)
|
||||
old = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||
else
|
||||
old = gtk_bitset_new_empty ();
|
||||
guint n_after;
|
||||
self->strictness = new_strictness;
|
||||
self->items = gtk_rb_tree_new (FilterNode,
|
||||
FilterAugment,
|
||||
gtk_filter_list_model_augment,
|
||||
NULL, NULL);
|
||||
n_after = gtk_filter_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (self->model));
|
||||
if (n_after > 0)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, 0, n_after);
|
||||
}
|
||||
else
|
||||
break;
|
||||
case GTK_FILTER_MATCH_ALL:
|
||||
{
|
||||
old = self->matches;
|
||||
guint start, end, n_before, n_after;
|
||||
self->strictness = new_strictness;
|
||||
self->items = gtk_rb_tree_new (FilterNode,
|
||||
FilterAugment,
|
||||
gtk_filter_list_model_augment,
|
||||
NULL, NULL);
|
||||
n_before = g_list_model_get_n_items (self->model);
|
||||
gtk_filter_list_model_add_items (self, NULL, 0, n_before);
|
||||
if (gtk_filter_list_model_find_filtered (self, &start, &end, &n_after))
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), start, n_before - end - start, n_after - end - start);
|
||||
}
|
||||
self->strictness = new_strictness;
|
||||
switch (change)
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case GTK_FILTER_CHANGE_DIFFERENT:
|
||||
self->matches = gtk_bitset_new_empty ();
|
||||
pending = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||
break;
|
||||
case GTK_FILTER_CHANGE_LESS_STRICT:
|
||||
self->matches = gtk_bitset_copy (old);
|
||||
pending = gtk_bitset_new_range (0, g_list_model_get_n_items (self->model));
|
||||
gtk_bitset_subtract (pending, self->matches);
|
||||
break;
|
||||
case GTK_FILTER_CHANGE_MORE_STRICT:
|
||||
self->matches = gtk_bitset_new_empty ();
|
||||
pending = gtk_bitset_copy (old);
|
||||
break;
|
||||
}
|
||||
gtk_filter_list_model_start_filtering (self, pending);
|
||||
|
||||
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case GTK_FILTER_MATCH_SOME:
|
||||
gtk_filter_list_model_refilter (self);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,7 +616,7 @@ gtk_filter_list_model_filter_changed_cb (GtkFilter *filter,
|
||||
GtkFilterChange change,
|
||||
GtkFilterListModel *self)
|
||||
{
|
||||
gtk_filter_list_model_refilter (self, change);
|
||||
gtk_filter_list_model_update_strictness_and_refilter (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -548,7 +636,7 @@ gtk_filter_list_model_dispose (GObject *object)
|
||||
|
||||
gtk_filter_list_model_clear_model (self);
|
||||
gtk_filter_list_model_clear_filter (self);
|
||||
g_clear_pointer (&self->matches, gtk_bitset_unref);
|
||||
g_clear_pointer (&self->items, gtk_rb_tree_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_filter_list_model_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -574,18 +662,6 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
|
||||
GTK_TYPE_FILTER,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkFilterListModel:incremental:
|
||||
*
|
||||
* If the model should filter items incrementally
|
||||
*/
|
||||
properties[PROP_INCREMENTAL] =
|
||||
g_param_spec_boolean ("incremental",
|
||||
P_("Incremental"),
|
||||
P_("Filer items incrementally"),
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkFilterListModel:item-type:
|
||||
*
|
||||
@@ -608,19 +684,7 @@ gtk_filter_list_model_class_init (GtkFilterListModelClass *class)
|
||||
P_("Model"),
|
||||
P_("The model being filtered"),
|
||||
G_TYPE_LIST_MODEL,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkFilterListModel:pending:
|
||||
*
|
||||
* Number of items not yet filtered
|
||||
*/
|
||||
properties[PROP_PENDING] =
|
||||
g_param_spec_uint ("pending",
|
||||
P_("Pending"),
|
||||
P_("Number of items not yet filtered"),
|
||||
0, G_MAXUINT, 0,
|
||||
GTK_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
@@ -664,7 +728,7 @@ gtk_filter_list_model_new (GListModel *model,
|
||||
*
|
||||
* Creates a new empty filter list model set up to return items of type @item_type.
|
||||
* It is up to the application to set a proper filter and model to ensure
|
||||
* the item type is matches.
|
||||
* the item type is matched.
|
||||
*
|
||||
* Returns: a new #GtkFilterListModel
|
||||
**/
|
||||
@@ -705,7 +769,7 @@ gtk_filter_list_model_set_filter (GtkFilterListModel *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_filter_list_model_refilter (self, GTK_FILTER_CHANGE_LESS_STRICT);
|
||||
gtk_filter_list_model_update_strictness_and_refilter (self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILTER]);
|
||||
@@ -764,18 +828,13 @@ gtk_filter_list_model_set_model (GtkFilterListModel *self,
|
||||
if (removed == 0)
|
||||
{
|
||||
self->strictness = GTK_FILTER_MATCH_NONE;
|
||||
gtk_filter_list_model_refilter (self, GTK_FILTER_CHANGE_LESS_STRICT);
|
||||
gtk_filter_list_model_update_strictness_and_refilter (self);
|
||||
added = 0;
|
||||
}
|
||||
else if (self->matches)
|
||||
{
|
||||
gtk_filter_list_model_start_filtering (self, gtk_bitset_new_range (0, g_list_model_get_n_items (model)));
|
||||
added = gtk_bitset_get_size (self->matches);
|
||||
}
|
||||
else if (self->items)
|
||||
added = gtk_filter_list_model_add_items (self, NULL, 0, g_list_model_get_n_items (model));
|
||||
else
|
||||
{
|
||||
added = g_list_model_get_n_items (model);
|
||||
}
|
||||
added = g_list_model_get_n_items (model);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -805,89 +864,54 @@ gtk_filter_list_model_get_model (GtkFilterListModel *self)
|
||||
return self->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_filter_list_model_set_incremental:
|
||||
* @self: a #GtkFilterListModel
|
||||
* @incremental: %TRUE to enable incremental filtering
|
||||
*
|
||||
* When incremental filtering is enabled, the filterlistmodel will not run
|
||||
* filters immediately, but will instead queue an idle handler that
|
||||
* incrementally filters the items and adds them to the list. This of course
|
||||
* means that items are not instantly added to the list, but only appear
|
||||
* incrementally.
|
||||
*
|
||||
* When your filter blocks the UI while filtering, you might consider
|
||||
* turning this on. Depending on your model and filters, this may become
|
||||
* interesting around 10,000 to 100,000 items.
|
||||
*
|
||||
* By default, incremental filtering is disabled.
|
||||
**/
|
||||
void
|
||||
gtk_filter_list_model_set_incremental (GtkFilterListModel *self,
|
||||
gboolean incremental)
|
||||
static void
|
||||
gtk_filter_list_model_refilter (GtkFilterListModel *self)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
|
||||
FilterNode *node;
|
||||
guint i, first_change, last_change;
|
||||
guint n_is_visible, n_was_visible;
|
||||
gboolean visible;
|
||||
|
||||
if (self->incremental == incremental)
|
||||
g_return_if_fail (GTK_IS_FILTER_LIST_MODEL (self));
|
||||
|
||||
if (self->items == NULL || self->model == NULL)
|
||||
return;
|
||||
|
||||
self->incremental = incremental;
|
||||
|
||||
if (!incremental)
|
||||
first_change = G_MAXUINT;
|
||||
last_change = 0;
|
||||
n_is_visible = 0;
|
||||
n_was_visible = 0;
|
||||
for (i = 0, node = gtk_rb_tree_get_first (self->items);
|
||||
node != NULL;
|
||||
i++, node = gtk_rb_tree_node_get_next (node))
|
||||
{
|
||||
GtkBitset *old;
|
||||
gtk_filter_list_model_run_filter (self, G_MAXUINT);
|
||||
visible = gtk_filter_list_model_run_filter (self, i);
|
||||
if (visible == node->visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
n_is_visible++;
|
||||
n_was_visible++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
old = gtk_bitset_copy (self->matches);
|
||||
gtk_filter_list_model_run_filter (self, 512);
|
||||
|
||||
gtk_filter_list_model_stop_filtering (self);
|
||||
|
||||
gtk_filter_list_model_emit_items_changed_for_changes (self, old);
|
||||
node->visible = visible;
|
||||
gtk_rb_tree_node_mark_dirty (node);
|
||||
first_change = MIN (n_is_visible, first_change);
|
||||
if (visible)
|
||||
n_is_visible++;
|
||||
else
|
||||
n_was_visible++;
|
||||
last_change = MAX (n_is_visible, last_change);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_INCREMENTAL]);
|
||||
if (first_change <= last_change)
|
||||
{
|
||||
g_list_model_items_changed (G_LIST_MODEL (self),
|
||||
first_change,
|
||||
last_change - first_change + n_was_visible - n_is_visible,
|
||||
last_change - first_change);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_filter_list_model_get_incremental:
|
||||
* @self: a #GtkFilterListModel
|
||||
*
|
||||
* Returns whether incremental filtering was enabled via
|
||||
* gtk_filter_list_model_set_incremental().
|
||||
*
|
||||
* Returns: %TRUE if incremental filtering is enabled
|
||||
**/
|
||||
gboolean
|
||||
gtk_filter_list_model_get_incremental (GtkFilterListModel *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILTER_LIST_MODEL (self), FALSE);
|
||||
|
||||
return self->incremental;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_filter_list_model_get_pending:
|
||||
* @self: a #GtkFilterListModel
|
||||
*
|
||||
* Returns the number of items that have not been filtered yet.
|
||||
*
|
||||
* When incremental filtering is not enabled, this always returns 0.
|
||||
*
|
||||
* You can use this value to check if @self is busy filtering by
|
||||
* comparing the return value to 0 or you can compute the percentage
|
||||
* of the filter remaining by dividing the return value by
|
||||
* g_list_model_get_n_items(gtk_filter_list_model_get_model (self)).
|
||||
*
|
||||
* Returns: The number of items not yet filtered
|
||||
**/
|
||||
guint
|
||||
gtk_filter_list_model_get_pending (GtkFilterListModel *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILTER_LIST_MODEL (self), FALSE);
|
||||
|
||||
if (self->pending == NULL)
|
||||
return 0;
|
||||
|
||||
return gtk_bitset_get_size (self->pending);
|
||||
}
|
||||
|
||||
@@ -52,14 +52,6 @@ void gtk_filter_list_model_set_model (GtkFilterListMo
|
||||
GListModel *model);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_filter_list_model_get_model (GtkFilterListModel *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_filter_list_model_set_incremental (GtkFilterListModel *self,
|
||||
gboolean incremental);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_filter_list_model_get_incremental (GtkFilterListModel *self);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_filter_list_model_get_pending (GtkFilterListModel *self);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkfunctionslistitemfactory.h"
|
||||
|
||||
#include "gtklistitemfactoryprivate.h"
|
||||
#include "gtklistitemprivate.h"
|
||||
|
||||
struct _GtkFunctionsListItemFactory
|
||||
{
|
||||
GtkListItemFactory parent_instance;
|
||||
|
||||
GtkListItemSetupFunc setup_func;
|
||||
GtkListItemBindFunc bind_func;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_destroy;
|
||||
};
|
||||
|
||||
struct _GtkFunctionsListItemFactoryClass
|
||||
{
|
||||
GtkListItemFactoryClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkFunctionsListItemFactory, gtk_functions_list_item_factory, GTK_TYPE_LIST_ITEM_FACTORY)
|
||||
|
||||
static void
|
||||
gtk_functions_list_item_factory_setup (GtkListItemFactory *factory,
|
||||
GtkListItemWidget *widget,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory);
|
||||
|
||||
if (self->setup_func)
|
||||
self->setup_func (list_item, self->user_data);
|
||||
|
||||
GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->setup (factory, widget, list_item);
|
||||
|
||||
if (gtk_list_item_get_item (list_item) != NULL && self->bind_func)
|
||||
self->bind_func (list_item, self->user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_functions_list_item_factory_update (GtkListItemFactory *factory,
|
||||
GtkListItemWidget *widget,
|
||||
GtkListItem *list_item,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (factory);
|
||||
|
||||
GTK_LIST_ITEM_FACTORY_CLASS (gtk_functions_list_item_factory_parent_class)->update (factory, widget, list_item, position, item, selected);
|
||||
|
||||
if (item != NULL && self->bind_func)
|
||||
self->bind_func (list_item, self->user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_functions_list_item_factory_finalize (GObject *object)
|
||||
{
|
||||
GtkFunctionsListItemFactory *self = GTK_FUNCTIONS_LIST_ITEM_FACTORY (object);
|
||||
|
||||
if (self->user_destroy)
|
||||
self->user_destroy (self->user_data);
|
||||
|
||||
G_OBJECT_CLASS (gtk_functions_list_item_factory_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_functions_list_item_factory_class_init (GtkFunctionsListItemFactoryClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkListItemFactoryClass *factory_class = GTK_LIST_ITEM_FACTORY_CLASS (klass);
|
||||
|
||||
object_class->finalize = gtk_functions_list_item_factory_finalize;
|
||||
|
||||
factory_class->setup = gtk_functions_list_item_factory_setup;
|
||||
factory_class->update = gtk_functions_list_item_factory_update;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_functions_list_item_factory_init (GtkFunctionsListItemFactory *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_functions_list_item_factory_new: (skip)
|
||||
* @setup_func: (scope call) (destroy user_destroy): the setup function for the list item factory
|
||||
* @bind_func: (scope call) (destroy user_destroy): the bind function for the list item factory
|
||||
* @user_data: user data for the @setup_func and @bind_func functions
|
||||
* @user_destroy: a function called to destroy @user_data
|
||||
*
|
||||
* Creates a new #GtkListItemFactory with the given functions.
|
||||
*
|
||||
* Returns: (transfer full): the newly created list item factory object
|
||||
*/
|
||||
GtkListItemFactory *
|
||||
gtk_functions_list_item_factory_new (GtkListItemSetupFunc setup_func,
|
||||
GtkListItemBindFunc bind_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy)
|
||||
{
|
||||
GtkFunctionsListItemFactory *self;
|
||||
|
||||
g_return_val_if_fail (setup_func || bind_func, NULL);
|
||||
g_return_val_if_fail (user_data != NULL || user_destroy == NULL, NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, NULL);
|
||||
|
||||
self->setup_func = setup_func;
|
||||
self->bind_func = bind_func;
|
||||
self->user_data = user_data;
|
||||
self->user_destroy = user_destroy;
|
||||
|
||||
return GTK_LIST_ITEM_FACTORY (self);
|
||||
}
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __GTK_FUNCTIONS_LIST_ITEM_FACTORY_H__
|
||||
#define __GTK_FUNCTIONS_LIST_ITEM_FACTORY_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtklistitemfactory.h>
|
||||
#include <gtk/gtklistitem.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY (gtk_functions_list_item_factory_get_type ())
|
||||
#define GTK_FUNCTIONS_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, GtkFunctionsListItemFactory))
|
||||
#define GTK_FUNCTIONS_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, GtkFunctionsListItemFactoryClass))
|
||||
#define GTK_IS_FUNCTIONS_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY))
|
||||
#define GTK_IS_FUNCTIONS_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY))
|
||||
#define GTK_FUNCTIONS_LIST_ITEM_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_FUNCTIONS_LIST_ITEM_FACTORY, GtkFunctionsListItemFactoryClass))
|
||||
|
||||
typedef struct _GtkFunctionsListItemFactory GtkFunctionsListItemFactory;
|
||||
typedef struct _GtkFunctionsListItemFactoryClass GtkFunctionsListItemFactoryClass;
|
||||
|
||||
/**
|
||||
* GtkListItemSetupFunc:
|
||||
* @item: the #GtkListItem to set up
|
||||
* @user_data: (closure): user data
|
||||
*
|
||||
* Called whenever a new list item needs to be setup for managing a row in
|
||||
* the list.
|
||||
*
|
||||
* At this point, the list item is not bound yet, so gtk_list_item_get_item()
|
||||
* will return %NULL.
|
||||
* The list item will later be bound to an item via the #GtkListItemBindFunc.
|
||||
*/
|
||||
typedef void (* GtkListItemSetupFunc) (GtkListItem *item, gpointer user_data);
|
||||
|
||||
/**
|
||||
* GtkListItemBindFunc:
|
||||
* @item: the #GtkListItem to bind
|
||||
* @user_data: (closure): user data
|
||||
*
|
||||
* Binds a#GtkListItem previously set up via a #GtkListItemSetupFunc to
|
||||
* an @item.
|
||||
*
|
||||
* Rebinding a @item to different @items is supported as well as
|
||||
* unbinding it by setting @item to %NULL.
|
||||
*/
|
||||
typedef void (* GtkListItemBindFunc) (GtkListItem *item,
|
||||
gpointer user_data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType gtk_functions_list_item_factory_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkListItemFactory * gtk_functions_list_item_factory_new (GtkListItemSetupFunc setup_func,
|
||||
GtkListItemBindFunc bind_func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_FUNCTIONS_LIST_ITEM_FACTORY_H__ */
|
||||
@@ -1171,6 +1171,8 @@ gtk_grid_view_init (GtkGridView *self)
|
||||
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
|
||||
self->max_columns * GTK_GRID_VIEW_MAX_VISIBLE_ROWS,
|
||||
self->max_columns);
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "view");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+3
-1
@@ -595,7 +595,7 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class)
|
||||
g_param_spec_boolean ("show-title-buttons",
|
||||
P_("Show title buttons"),
|
||||
P_("Whether to show title buttons"),
|
||||
FALSE,
|
||||
TRUE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
@@ -629,6 +629,7 @@ gtk_header_bar_init (GtkHeaderBar *bar)
|
||||
|
||||
priv->title_widget = NULL;
|
||||
priv->decoration_layout = NULL;
|
||||
priv->show_title_buttons = TRUE;
|
||||
priv->state = GDK_SURFACE_STATE_WITHDRAWN;
|
||||
|
||||
priv->handle = gtk_window_handle_new ();
|
||||
@@ -646,6 +647,7 @@ gtk_header_bar_init (GtkHeaderBar *bar)
|
||||
gtk_center_box_set_end_widget (GTK_CENTER_BOX (priv->center_box), priv->end_box);
|
||||
|
||||
construct_title_label (bar);
|
||||
create_window_controls (bar);
|
||||
}
|
||||
|
||||
static GtkBuildableIface *parent_buildable_iface;
|
||||
|
||||
+7
-4
@@ -3573,12 +3573,15 @@ static void
|
||||
gtk_label_unrealize (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *self = GTK_LABEL (widget);
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
clipboard = gtk_widget_get_primary_clipboard (widget);
|
||||
if (self->select_info &&
|
||||
gdk_clipboard_get_content (clipboard) == self->select_info->provider)
|
||||
gdk_clipboard_set_content (clipboard, NULL);
|
||||
self->select_info->provider)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_primary_clipboard (widget);
|
||||
|
||||
if (gdk_clipboard_get_content (clipboard) == self->select_info->provider)
|
||||
gdk_clipboard_set_content (clipboard, NULL);
|
||||
}
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_label_parent_class)->unrealize (widget);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
* Because views do not display the whole list at once but only a few
|
||||
* items, they only need to maintain a few widgets at a time. They will
|
||||
* instruct the #GtkListItemFactory to create these widgets and bind them
|
||||
* to the items that are currently displayed.
|
||||
* to the items that are currently displayed.
|
||||
* As the list model changes or the user scrolls to the list, the items will
|
||||
* change and the view will instruct the factory to bind the widgets to those
|
||||
* new items.
|
||||
@@ -56,13 +56,13 @@
|
||||
* Various implementations of #GtkListItemFactory exist to allow you different
|
||||
* ways to provide those widgets. The most common implementations are
|
||||
* #GtkBuilderListItemFactory which takes a #GtkBuilder .ui file and then creates
|
||||
* and manages widgets everything automatically from the information in that file
|
||||
* widgets and manages everything automatically from the information in that file
|
||||
* and #GtkSignalListItemFactory which allows you to connect to signals with your
|
||||
* own code and retain full control over how the widgets are setup and managed.
|
||||
*
|
||||
* A #GtkListItemFactory is supposed to be final - that means its behavior should
|
||||
* not change and the first widget created from it should behave the same way as
|
||||
* the last widget created from it.
|
||||
* the last widget created from it.
|
||||
* If you intend to do changes to the behavior, it is recommended that you create
|
||||
* a new #GtkListItemFactory which will allow the views to recreate its widgets.
|
||||
*
|
||||
|
||||
@@ -925,6 +925,8 @@ gtk_list_view_init (GtkListView *self)
|
||||
gtk_list_base_set_anchor_max_widgets (GTK_LIST_BASE (self),
|
||||
GTK_LIST_VIEW_MAX_LIST_ITEMS,
|
||||
GTK_LIST_VIEW_EXTRA_ITEMS);
|
||||
|
||||
gtk_widget_add_css_class (GTK_WIDGET (self), "view");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -386,3 +386,19 @@ gtk_multi_selection_new (GListModel *model)
|
||||
"model", model,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_multi_selection_get_model:
|
||||
* @self: a #GtkMultiSelection
|
||||
*
|
||||
* Returns the underlying model of @self.
|
||||
*
|
||||
* Returns: (transfer none): the underlying model
|
||||
*/
|
||||
GListModel *
|
||||
gtk_multi_selection_get_model (GtkMultiSelection *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_MULTI_SELECTION (self), NULL);
|
||||
|
||||
return self->model;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ G_DECLARE_FINAL_TYPE (GtkMultiSelection, gtk_multi_selection, GTK, MULTI_SELECTI
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_multi_selection_new (GListModel *model);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_multi_selection_get_model (GtkMultiSelection *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -250,16 +250,6 @@ G_DEFINE_TYPE_WITH_CODE (GtkRange, gtk_range, GTK_TYPE_WIDGET,
|
||||
static guint signals[LAST_SIGNAL];
|
||||
static GParamSpec *properties[LAST_PROP];
|
||||
|
||||
static void
|
||||
gtk_range_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkRange *range = GTK_RANGE (widget);
|
||||
GtkRangePrivate *priv = gtk_range_get_instance_private (range);
|
||||
|
||||
gtk_widget_snapshot_child (widget, priv->trough_widget, snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_range_class_init (GtkRangeClass *class)
|
||||
{
|
||||
@@ -275,7 +265,6 @@ gtk_range_class_init (GtkRangeClass *class)
|
||||
gobject_class->dispose = gtk_range_dispose;
|
||||
|
||||
widget_class->measure = gtk_range_measure;
|
||||
widget_class->snapshot = gtk_range_snapshot;
|
||||
widget_class->size_allocate = gtk_range_size_allocate;
|
||||
widget_class->unmap = gtk_range_unmap;
|
||||
widget_class->direction_changed = gtk_range_direction_changed;
|
||||
|
||||
+14
-12
@@ -47,14 +47,12 @@ static void
|
||||
gtk_theming_background_snapshot_color (GtkCssBoxes *boxes,
|
||||
GtkSnapshot *snapshot,
|
||||
const GdkRGBA *bg_color,
|
||||
const GtkCssValue *background_image)
|
||||
guint n_bg_values)
|
||||
{
|
||||
const GskRoundedRect *box;
|
||||
gint n_values;
|
||||
GtkCssArea clip;
|
||||
|
||||
n_values = _gtk_css_array_value_get_n_values (background_image);
|
||||
clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (boxes->style->background->background_clip, n_values - 1));
|
||||
|
||||
clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (boxes->style->background->background_clip, n_bg_values - 1));
|
||||
box = gtk_css_boxes_get_box (boxes, clip);
|
||||
|
||||
if (gsk_rounded_rect_is_rectilinear (box))
|
||||
@@ -94,9 +92,6 @@ gtk_theming_background_snapshot_layer (GtkCssBoxes *bg,
|
||||
|
||||
pos = _gtk_css_array_value_get_nth (background->background_position, idx);
|
||||
repeat = _gtk_css_array_value_get_nth (background->background_repeat, idx);
|
||||
hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
|
||||
vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
|
||||
|
||||
|
||||
origin = gtk_css_boxes_get_box (bg,
|
||||
_gtk_css_area_value_get (
|
||||
@@ -125,8 +120,13 @@ gtk_theming_background_snapshot_layer (GtkCssBoxes *bg,
|
||||
/* optimization */
|
||||
if (image_width == width)
|
||||
hrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
|
||||
else
|
||||
hrepeat = _gtk_css_background_repeat_value_get_x (repeat);
|
||||
|
||||
if (image_height == height)
|
||||
vrepeat = GTK_CSS_REPEAT_STYLE_NO_REPEAT;
|
||||
else
|
||||
vrepeat = _gtk_css_background_repeat_value_get_y (repeat);
|
||||
|
||||
gtk_snapshot_push_debug (snapshot, "Layer %u", idx);
|
||||
gtk_snapshot_push_rounded_clip (snapshot, clip);
|
||||
@@ -262,7 +262,8 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
gboolean has_bg_color;
|
||||
gboolean has_bg_image;
|
||||
gboolean has_shadow;
|
||||
gint idx;
|
||||
int idx;
|
||||
guint number_of_layers;
|
||||
|
||||
if (background->base.type == GTK_CSS_BACKGROUND_INITIAL_VALUES)
|
||||
return;
|
||||
@@ -286,10 +287,11 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
snapshot,
|
||||
gtk_css_boxes_get_border_box (boxes));
|
||||
|
||||
number_of_layers = _gtk_css_array_value_get_n_values (background_image);
|
||||
|
||||
if (has_bg_image)
|
||||
{
|
||||
GtkCssValue *blend_modes = background->background_blend_mode;
|
||||
const int number_of_layers = _gtk_css_array_value_get_n_values (background_image);
|
||||
GskBlendMode *blend_mode_values = g_alloca (sizeof (GskBlendMode) * number_of_layers);
|
||||
|
||||
for (idx = number_of_layers - 1; idx >= 0; idx--)
|
||||
@@ -301,7 +303,7 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
}
|
||||
|
||||
if (has_bg_color)
|
||||
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, background_image);
|
||||
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, number_of_layers);
|
||||
|
||||
for (idx = number_of_layers - 1; idx >= 0; idx--)
|
||||
{
|
||||
@@ -319,7 +321,7 @@ gtk_css_style_snapshot_background (GtkCssBoxes *boxes,
|
||||
}
|
||||
else if (has_bg_color)
|
||||
{
|
||||
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, background_image);
|
||||
gtk_theming_background_snapshot_color (boxes, snapshot, bg_color, number_of_layers);
|
||||
}
|
||||
|
||||
if (has_shadow)
|
||||
|
||||
+14
-44
@@ -79,22 +79,23 @@
|
||||
*
|
||||
* |[<!-- language="plain" -->
|
||||
* scale[.fine-tune][.marks-before][.marks-after]
|
||||
* ├── [value][.top][.right][.bottom][.left]
|
||||
* ├── marks.top
|
||||
* │ ├── mark
|
||||
* │ ┊ ├── [label]
|
||||
* │ ┊ ╰── indicator
|
||||
* ┊ ┊
|
||||
* │ ╰── mark
|
||||
* ├── [value][.top][.right][.bottom][.left]
|
||||
* ├── trough
|
||||
* │ ├── [fill]
|
||||
* │ ├── [highlight]
|
||||
* │ ╰── slider
|
||||
* ╰── marks.bottom
|
||||
* ├── mark
|
||||
* ┊ ├── indicator
|
||||
* ┊ ╰── [label]
|
||||
* ╰── mark
|
||||
* ├── marks.bottom
|
||||
* │ ├── mark
|
||||
* │ ┊ ├── indicator
|
||||
* │ ┊ ╰── [label]
|
||||
* ┊ ┊
|
||||
* │ ╰── mark
|
||||
* ╰── trough
|
||||
* ├── [fill]
|
||||
* ├── [highlight]
|
||||
* ╰── slider
|
||||
* ]|
|
||||
*
|
||||
* GtkScale has a main CSS node with name scale and a subnode for its contents,
|
||||
@@ -197,8 +198,6 @@ static void gtk_scale_measure (GtkWidget *widget,
|
||||
static void gtk_scale_get_range_border (GtkRange *range,
|
||||
GtkBorder *border);
|
||||
static void gtk_scale_finalize (GObject *object);
|
||||
static void gtk_scale_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot);
|
||||
static void gtk_scale_real_get_layout_offsets (GtkScale *scale,
|
||||
gint *x,
|
||||
gint *y);
|
||||
@@ -661,7 +660,6 @@ gtk_scale_class_init (GtkScaleClass *class)
|
||||
gobject_class->notify = gtk_scale_notify;
|
||||
gobject_class->finalize = gtk_scale_finalize;
|
||||
|
||||
widget_class->snapshot = gtk_scale_snapshot;
|
||||
widget_class->size_allocate = gtk_scale_size_allocate;
|
||||
widget_class->measure = gtk_scale_measure;
|
||||
widget_class->grab_focus = gtk_widget_grab_focus_self;
|
||||
@@ -1093,14 +1091,9 @@ gtk_scale_set_draw_value (GtkScale *scale,
|
||||
"css-name", "value",
|
||||
"label", txt,
|
||||
NULL);
|
||||
|
||||
g_free (txt);
|
||||
|
||||
if (priv->value_pos == GTK_POS_TOP || priv->value_pos == GTK_POS_LEFT)
|
||||
gtk_widget_insert_after (priv->value_widget, GTK_WIDGET (scale), NULL);
|
||||
else
|
||||
gtk_widget_insert_before (priv->value_widget, GTK_WIDGET (scale), NULL);
|
||||
|
||||
gtk_widget_insert_after (priv->value_widget, GTK_WIDGET (scale), NULL);
|
||||
gtk_range_set_round_digits (GTK_RANGE (scale), priv->digits);
|
||||
update_value_position (scale);
|
||||
update_label_request (scale);
|
||||
@@ -1469,25 +1462,6 @@ gtk_scale_measure (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scale_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkScale *scale = GTK_SCALE (widget);
|
||||
GtkScalePrivate *priv = gtk_scale_get_instance_private (scale);
|
||||
|
||||
if (priv->top_marks_widget)
|
||||
gtk_widget_snapshot_child (widget, priv->top_marks_widget, snapshot);
|
||||
|
||||
if (priv->bottom_marks_widget)
|
||||
gtk_widget_snapshot_child (widget, priv->bottom_marks_widget, snapshot);
|
||||
|
||||
if (priv->value_widget)
|
||||
gtk_widget_snapshot_child (widget, priv->value_widget, snapshot);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_scale_parent_class)->snapshot (widget, snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_scale_real_get_layout_offsets (GtkScale *scale,
|
||||
gint *x,
|
||||
@@ -1722,9 +1696,7 @@ gtk_scale_add_mark (GtkScale *scale,
|
||||
|
||||
gtk_widget_insert_after (priv->top_marks_widget,
|
||||
GTK_WIDGET (scale),
|
||||
(priv->value_widget &&
|
||||
(priv->value_pos == GTK_POS_TOP || priv->value_pos == GTK_POS_LEFT)) ?
|
||||
priv->value_widget : NULL);
|
||||
priv->value_widget);
|
||||
gtk_widget_add_css_class (priv->top_marks_widget, GTK_STYLE_CLASS_TOP);
|
||||
}
|
||||
marks_widget = priv->top_marks_widget;
|
||||
@@ -1742,9 +1714,7 @@ gtk_scale_add_mark (GtkScale *scale,
|
||||
|
||||
gtk_widget_insert_before (priv->bottom_marks_widget,
|
||||
GTK_WIDGET (scale),
|
||||
(priv->value_widget &&
|
||||
(priv->value_pos == GTK_POS_BOTTOM || priv->value_pos == GTK_POS_RIGHT)) ?
|
||||
priv->value_widget: NULL);
|
||||
gtk_range_get_trough_widget (GTK_RANGE (scale)));
|
||||
gtk_widget_add_css_class (priv->bottom_marks_widget, GTK_STYLE_CLASS_BOTTOM);
|
||||
}
|
||||
marks_widget = priv->bottom_marks_widget;
|
||||
|
||||
+13
-2
@@ -546,8 +546,19 @@ gtk_scrolled_window_compute_expand (GtkWidget *widget,
|
||||
gboolean *hexpand,
|
||||
gboolean *vexpand)
|
||||
{
|
||||
*hexpand = TRUE;
|
||||
*vexpand = TRUE;
|
||||
GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW (widget);
|
||||
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
|
||||
|
||||
if (priv->child)
|
||||
{
|
||||
*hexpand = gtk_widget_compute_expand (priv->child, GTK_ORIENTATION_HORIZONTAL);
|
||||
*vexpand = gtk_widget_compute_expand (priv->child, GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
*hexpand = FALSE;
|
||||
*vexpand = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright © 2020 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: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkselectionfiltermodel.h"
|
||||
#include "gtkbitset.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkselectionfiltermodel
|
||||
* @title: GtkSelectionFilterModel
|
||||
* @short_description: A list model that turns a selection in a model
|
||||
* @see_also: #GtkSelectionModel
|
||||
*
|
||||
* #GtkSelectionFilterModel is a list model that presents the
|
||||
* selected items in a #GtkSelectionModel as its own list model.
|
||||
*/
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ITEM_TYPE,
|
||||
PROP_MODEL,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
struct _GtkSelectionFilterModel
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GType item_type;
|
||||
GtkSelectionModel *model;
|
||||
GtkBitset *selection;
|
||||
};
|
||||
|
||||
struct _GtkSelectionFilterModelClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
static GType
|
||||
gtk_selection_filter_model_get_item_type (GListModel *list)
|
||||
{
|
||||
GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (list);
|
||||
|
||||
return self->item_type;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_selection_filter_model_get_n_items (GListModel *list)
|
||||
{
|
||||
GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (list);
|
||||
|
||||
if (self->selection)
|
||||
return gtk_bitset_get_size (self->selection);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gtk_selection_filter_model_get_item (GListModel *list,
|
||||
guint position)
|
||||
{
|
||||
GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (list);
|
||||
|
||||
position = gtk_bitset_get_nth (self->selection, position);
|
||||
|
||||
return g_list_model_get_item (G_LIST_MODEL (self->model), position);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_list_model_init (GListModelInterface *iface)
|
||||
{
|
||||
iface->get_item_type = gtk_selection_filter_model_get_item_type;
|
||||
iface->get_n_items = gtk_selection_filter_model_get_n_items;
|
||||
iface->get_item = gtk_selection_filter_model_get_item;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkSelectionFilterModel, gtk_selection_filter_model, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, gtk_selection_filter_model_list_model_init))
|
||||
|
||||
static void
|
||||
selection_filter_model_items_changed (GtkSelectionFilterModel *self,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added)
|
||||
{
|
||||
GtkBitset *selection;
|
||||
guint sel_position = 0;
|
||||
guint sel_removed = 0;
|
||||
guint sel_added = 0;
|
||||
|
||||
selection = gtk_selection_model_get_selection (self->model);
|
||||
|
||||
if (position > 0)
|
||||
sel_position = gtk_bitset_get_size_in_range (self->selection, 0, position - 1);
|
||||
|
||||
if (removed > 0)
|
||||
sel_removed = gtk_bitset_get_size_in_range (self->selection, position, position + removed - 1);
|
||||
|
||||
if (added > 0)
|
||||
sel_added = gtk_bitset_get_size_in_range (selection, position, position + added - 1);
|
||||
|
||||
gtk_bitset_unref (self->selection);
|
||||
self->selection = gtk_bitset_copy (selection);
|
||||
|
||||
gtk_bitset_unref (selection);
|
||||
|
||||
if (sel_removed > 0 || sel_added > 0)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), sel_position, sel_removed, sel_added);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_items_changed_cb (GListModel *model,
|
||||
guint position,
|
||||
guint removed,
|
||||
guint added,
|
||||
GtkSelectionFilterModel *self)
|
||||
{
|
||||
selection_filter_model_items_changed (self, position, removed, added);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_selection_changed_cb (GListModel *model,
|
||||
guint position,
|
||||
guint n_items,
|
||||
GtkSelectionFilterModel *self)
|
||||
{
|
||||
selection_filter_model_items_changed (self, position, n_items, n_items);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ITEM_TYPE:
|
||||
self->item_type = g_value_get_gtype (value);
|
||||
break;
|
||||
|
||||
case PROP_MODEL:
|
||||
gtk_selection_filter_model_set_model (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ITEM_TYPE:
|
||||
g_value_set_gtype (value, self->item_type);
|
||||
break;
|
||||
|
||||
case PROP_MODEL:
|
||||
g_value_set_object (value, self->model);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_clear_model (GtkSelectionFilterModel *self)
|
||||
{
|
||||
if (self->model == NULL)
|
||||
return;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (self->model, gtk_selection_filter_model_items_changed_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (self->model, gtk_selection_filter_model_selection_changed_cb, self);
|
||||
|
||||
g_clear_object (&self->model);
|
||||
g_clear_pointer (&self->selection, gtk_bitset_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_dispose (GObject *object)
|
||||
{
|
||||
GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (object);
|
||||
|
||||
gtk_selection_filter_model_clear_model (self);
|
||||
|
||||
G_OBJECT_CLASS (gtk_selection_filter_model_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_class_init (GtkSelectionFilterModelClass *class)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
gobject_class->set_property = gtk_selection_filter_model_set_property;
|
||||
gobject_class->get_property = gtk_selection_filter_model_get_property;
|
||||
gobject_class->dispose = gtk_selection_filter_model_dispose;
|
||||
|
||||
/**
|
||||
* GtkSelectionFilterModel:item-type:
|
||||
*
|
||||
* The #GType for elements of this object
|
||||
*/
|
||||
properties[PROP_ITEM_TYPE] =
|
||||
g_param_spec_gtype ("item-type",
|
||||
P_("Item type"),
|
||||
P_("The type of elements of this object"),
|
||||
G_TYPE_OBJECT,
|
||||
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
* GtkSelectionFilterModel:model:
|
||||
*
|
||||
* The model being filtered
|
||||
*/
|
||||
properties[PROP_MODEL] =
|
||||
g_param_spec_object ("model",
|
||||
P_("Model"),
|
||||
P_("The model being filtered"),
|
||||
GTK_TYPE_SELECTION_MODEL,
|
||||
GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_selection_filter_model_init (GtkSelectionFilterModel *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_selection_filter_model_new:
|
||||
* @model: the selection model to filter
|
||||
*
|
||||
* Creates a new #GtkSelectionFilterModel that will include the
|
||||
* selected items from the underlying selection model.
|
||||
*
|
||||
* Returns: a new #GtkSelectionFilterModel
|
||||
**/
|
||||
GtkSelectionFilterModel *
|
||||
gtk_selection_filter_model_new (GtkSelectionModel *model)
|
||||
{
|
||||
GtkSelectionFilterModel *result;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), NULL);
|
||||
|
||||
result = g_object_new (GTK_TYPE_SELECTION_FILTER_MODEL,
|
||||
"item-type", g_list_model_get_item_type (G_LIST_MODEL (model)),
|
||||
"model", model,
|
||||
NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_selection_filter_model_new_for_type:
|
||||
* @item_type: the type of the items that will be returned
|
||||
*
|
||||
* Creates a new empty selection filter model set up to return items
|
||||
* of type @item_type. It is up to the application to set a proper
|
||||
* selection model to ensure the item type is matched.
|
||||
*
|
||||
* Returns: a new #GtkSelectionFilterModel
|
||||
**/
|
||||
GtkSelectionFilterModel *
|
||||
gtk_selection_filter_model_new_for_type (GType item_type)
|
||||
{
|
||||
g_return_val_if_fail (g_type_is_a (item_type, G_TYPE_OBJECT), NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_SELECTION_FILTER_MODEL,
|
||||
"item-type", item_type,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_selection_filter_model_set_model:
|
||||
* @self: a #GtkSelectionFilterModel
|
||||
* @model: (allow-none): The model to be filtered
|
||||
*
|
||||
* Sets the model to be filtered.
|
||||
*
|
||||
* Note that GTK makes no effort to ensure that @model conforms to
|
||||
* the item type of @self. It assumes that the caller knows what they
|
||||
* are doing and have set up an appropriate filter to ensure that item
|
||||
* types match.
|
||||
**/
|
||||
void
|
||||
gtk_selection_filter_model_set_model (GtkSelectionFilterModel *self,
|
||||
GtkSelectionModel *model)
|
||||
{
|
||||
guint removed, added;
|
||||
|
||||
g_return_if_fail (GTK_IS_SELECTION_FILTER_MODEL (self));
|
||||
g_return_if_fail (model == NULL || GTK_IS_SELECTION_MODEL (model));
|
||||
g_return_if_fail (model == NULL || g_type_is_a (g_list_model_get_item_type (G_LIST_MODEL (model)),
|
||||
self->item_type));
|
||||
|
||||
if (self->model == model)
|
||||
return;
|
||||
|
||||
removed = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
gtk_selection_filter_model_clear_model (self);
|
||||
|
||||
if (model)
|
||||
{
|
||||
GtkBitset *selection;
|
||||
|
||||
self->model = g_object_ref (model);
|
||||
|
||||
selection = gtk_selection_model_get_selection (self->model);
|
||||
self->selection = gtk_bitset_copy (selection);
|
||||
gtk_bitset_unref (selection);
|
||||
|
||||
g_signal_connect (model, "items-changed", G_CALLBACK (gtk_selection_filter_model_items_changed_cb), self);
|
||||
g_signal_connect (model, "selection-changed", G_CALLBACK (gtk_selection_filter_model_selection_changed_cb), self);
|
||||
}
|
||||
|
||||
added = g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
|
||||
if (removed > 0 || added > 0)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, removed, added);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_selection_filter_model_get_model:
|
||||
* @self: a #GtkSelectionFilterModel
|
||||
*
|
||||
* Gets the model currently filtered or %NULL if none.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): The model that gets filtered
|
||||
**/
|
||||
GtkSelectionModel *
|
||||
gtk_selection_filter_model_get_model (GtkSelectionFilterModel *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_SELECTION_FILTER_MODEL (self), NULL);
|
||||
|
||||
return self->model;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright © 2020 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: Matthias Clasen
|
||||
*/
|
||||
|
||||
#ifndef __GTK_SELECTION_FILTER_MODEL_H__
|
||||
#define __GTK_SELECTION_FILTER_MODEL_H__
|
||||
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <gtk/gtkselectionmodel.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_SELECTION_FILTER_MODEL (gtk_selection_filter_model_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkSelectionFilterModel, gtk_selection_filter_model, GTK, SELECTION_FILTER_MODEL, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSelectionFilterModel * gtk_selection_filter_model_new (GtkSelectionModel *model);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSelectionFilterModel * gtk_selection_filter_model_new_for_type (GType item_type);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_selection_filter_model_set_model (GtkSelectionFilterModel *self,
|
||||
GtkSelectionModel *model);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkSelectionModel * gtk_selection_filter_model_get_model (GtkSelectionFilterModel *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_SELECTION_FILTER_MODEL_H__ */
|
||||
@@ -860,9 +860,7 @@ gtk_shortcuts_window_init (GtkShortcutsWindow *self)
|
||||
priv->search_text_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
priv->search_image_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
|
||||
priv->header_bar = g_object_new (GTK_TYPE_HEADER_BAR,
|
||||
"show-title-buttons", TRUE,
|
||||
NULL);
|
||||
priv->header_bar = GTK_HEADER_BAR (gtk_header_bar_new ());
|
||||
gtk_window_set_titlebar (GTK_WINDOW (self), GTK_WIDGET (priv->header_bar));
|
||||
|
||||
search_button = g_object_new (GTK_TYPE_TOGGLE_BUTTON,
|
||||
|
||||
@@ -110,9 +110,9 @@ gtk_string_filter_match (GtkFilter *filter,
|
||||
!gtk_expression_evaluate (self->expression, item, &value))
|
||||
return FALSE;
|
||||
s = g_value_get_string (&value);
|
||||
prepared = gtk_string_filter_prepare (self, s);
|
||||
if (prepared == NULL)
|
||||
if (s == NULL)
|
||||
return FALSE;
|
||||
prepared = gtk_string_filter_prepare (self, s);
|
||||
|
||||
switch (self->match_mode)
|
||||
{
|
||||
|
||||
+85
-136
@@ -25,7 +25,6 @@
|
||||
#include "gtkbuilderprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkbitset.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkstringlist
|
||||
@@ -139,13 +138,31 @@ gtk_string_object_class_init (GtkStringObjectClass *class)
|
||||
|
||||
pspec = g_param_spec_string ("string", "String", "String",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_property (object_class, PROP_STRING, pspec);
|
||||
|
||||
}
|
||||
|
||||
static GtkStringObject *
|
||||
gtk_string_object_new (const char *string)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_STRING_OBJECT, "string", string, NULL);
|
||||
}
|
||||
|
||||
static GtkStringObject *
|
||||
gtk_string_object_new_take (char *string)
|
||||
{
|
||||
GtkStringObject *obj;
|
||||
|
||||
obj = g_object_new (GTK_TYPE_STRING_OBJECT, NULL);
|
||||
obj->string = string;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_string_object_get_string:
|
||||
* @self: a #GtkStringObject
|
||||
@@ -166,8 +183,7 @@ struct _GtkStringList
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GPtrArray *items;
|
||||
GtkBitset *objects;
|
||||
GSequence *items;
|
||||
};
|
||||
|
||||
struct _GtkStringListClass
|
||||
@@ -186,56 +202,7 @@ gtk_string_list_get_n_items (GListModel *list)
|
||||
{
|
||||
GtkStringList *self = GTK_STRING_LIST (list);
|
||||
|
||||
return self->items->len;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
IS_STRING (gpointer item)
|
||||
{
|
||||
return GPOINTER_TO_INT (item) & 0x1;
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
TO_STRING (gpointer item)
|
||||
{
|
||||
return GINT_TO_POINTER (GPOINTER_TO_INT (item) & ~0x1);
|
||||
}
|
||||
|
||||
static inline gpointer
|
||||
MAKE_STRING (const char *str)
|
||||
{
|
||||
return GINT_TO_POINTER (GPOINTER_TO_INT (str) | 0x1);
|
||||
}
|
||||
|
||||
static GtkStringObject *
|
||||
find_unused_object (GtkStringList *self)
|
||||
{
|
||||
GtkBitsetIter iter;
|
||||
guint position;
|
||||
gpointer item;
|
||||
|
||||
if (gtk_bitset_iter_init_first (&iter, self->objects, &position))
|
||||
{
|
||||
do
|
||||
{
|
||||
item = g_ptr_array_index (self->items, position);
|
||||
g_assert (!IS_STRING (item));
|
||||
if (G_OBJECT (item)->ref_count == 1)
|
||||
{
|
||||
GtkStringObject *obj;
|
||||
|
||||
obj = GTK_STRING_OBJECT (item);
|
||||
g_ptr_array_index (self->items, position) = MAKE_STRING (obj->string);
|
||||
obj->string = NULL;
|
||||
|
||||
gtk_bitset_remove (self->objects, position);
|
||||
|
||||
return obj;
|
||||
}
|
||||
} while (gtk_bitset_iter_next (&iter, &position));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return g_sequence_get_length (self->items);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
@@ -243,30 +210,14 @@ gtk_string_list_get_item (GListModel *list,
|
||||
guint position)
|
||||
{
|
||||
GtkStringList *self = GTK_STRING_LIST (list);
|
||||
gpointer item;
|
||||
GSequenceIter *iter;
|
||||
|
||||
if (position >= self->items->len)
|
||||
iter = g_sequence_get_iter_at_pos (self->items, position);
|
||||
|
||||
if (g_sequence_iter_is_end (iter))
|
||||
return NULL;
|
||||
|
||||
item = g_ptr_array_index (self->items, position);
|
||||
if (IS_STRING (item))
|
||||
{
|
||||
GtkStringObject *obj;
|
||||
|
||||
obj = find_unused_object (self);
|
||||
if (!obj)
|
||||
obj = g_object_new (GTK_TYPE_STRING_OBJECT, NULL);
|
||||
|
||||
obj->string = TO_STRING (item);
|
||||
g_ptr_array_index (self->items, position) = obj;
|
||||
gtk_bitset_add (self->objects, position);
|
||||
|
||||
item = obj;
|
||||
}
|
||||
|
||||
g_print ("live string objects: %lu\n", gtk_bitset_get_size (self->objects));
|
||||
|
||||
return g_object_ref (item);
|
||||
else
|
||||
return g_object_ref (g_sequence_get (iter));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -373,7 +324,7 @@ item_end_element (GtkBuildableParseContext *context,
|
||||
g_string_assign (data->string, translated);
|
||||
}
|
||||
|
||||
g_ptr_array_add (data->list->items, MAKE_STRING (g_strdup (data->string->str)));
|
||||
g_sequence_append (data->list->items, gtk_string_object_new (data->string->str));
|
||||
}
|
||||
|
||||
data->translatable = FALSE;
|
||||
@@ -453,8 +404,7 @@ gtk_string_list_dispose (GObject *object)
|
||||
{
|
||||
GtkStringList *self = GTK_STRING_LIST (object);
|
||||
|
||||
g_clear_pointer (&self->items, g_ptr_array_unref);
|
||||
g_clear_pointer (&self->objects, gtk_bitset_unref);
|
||||
g_clear_pointer (&self->items, g_sequence_free);
|
||||
|
||||
G_OBJECT_CLASS (gtk_string_list_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -467,20 +417,10 @@ gtk_string_list_class_init (GtkStringListClass *class)
|
||||
gobject_class->dispose = gtk_string_list_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
free_string_or_object (gpointer data)
|
||||
{
|
||||
if (IS_STRING (data))
|
||||
g_free (TO_STRING (data));
|
||||
else
|
||||
g_object_unref (data);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_string_list_init (GtkStringList *self)
|
||||
{
|
||||
self->items = g_ptr_array_new_full (32, free_string_or_object);
|
||||
self->objects = gtk_bitset_new_empty ();
|
||||
self->items = g_sequence_new (g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -492,13 +432,15 @@ gtk_string_list_init (GtkStringList *self)
|
||||
* Returns: a new #GtkStringList
|
||||
*/
|
||||
GtkStringList *
|
||||
gtk_string_list_new (const char * const *strings)
|
||||
gtk_string_list_new (const char **strings)
|
||||
{
|
||||
GtkStringList *self;
|
||||
guint i;
|
||||
|
||||
self = g_object_new (GTK_TYPE_STRING_LIST, NULL);
|
||||
|
||||
gtk_string_list_splice (self, 0, 0, strings);
|
||||
for (i = 0; strings[i]; i++)
|
||||
g_sequence_append (self->items, gtk_string_object_new (strings[i]));
|
||||
|
||||
return self;
|
||||
}
|
||||
@@ -508,10 +450,11 @@ gtk_string_list_new (const char * const *strings)
|
||||
* @self: a #GtkStringList
|
||||
* @position: the position at which to make the change
|
||||
* @n_removals: the number of strings to remove
|
||||
* @additions: (array zero-terminated=1) (nullable): The strings to add
|
||||
* @additions: (array length=n_additions): the strings to add
|
||||
* @n_additions: the number of items to add
|
||||
*
|
||||
* Changes @self by removing @n_removals strings and adding @additions
|
||||
* to it.
|
||||
* Changes @self by removing @n_removals strings and adding @n_additions
|
||||
* strings to it.
|
||||
*
|
||||
* This function is more efficient than gtk_string_list_insert() and
|
||||
* gtk_string_list_remove(), because it only emits
|
||||
@@ -524,41 +467,44 @@ gtk_string_list_new (const char * const *strings)
|
||||
* of the list at the time this function is called).
|
||||
*/
|
||||
void
|
||||
gtk_string_list_splice (GtkStringList *self,
|
||||
guint position,
|
||||
guint n_removals,
|
||||
const char * const *additions)
|
||||
gtk_string_list_splice (GtkStringList *self,
|
||||
guint position,
|
||||
guint n_removals,
|
||||
const char **additions,
|
||||
guint n_additions)
|
||||
{
|
||||
GSequenceIter *it;
|
||||
guint n_items;
|
||||
guint i;
|
||||
guint n_additions;
|
||||
gpointer item;
|
||||
|
||||
g_return_if_fail (GTK_IS_STRING_LIST (self));
|
||||
g_return_if_fail (position + n_removals >= position); /* overflow */
|
||||
|
||||
n_items = self->items->len;
|
||||
n_items = g_sequence_get_length (self->items);
|
||||
g_return_if_fail (position + n_removals <= n_items);
|
||||
|
||||
for (i = 0; i < n_removals; i++)
|
||||
g_ptr_array_remove_index (self->items, position);
|
||||
it = g_sequence_get_iter_at_pos (self->items, position);
|
||||
|
||||
if (additions)
|
||||
if (n_removals)
|
||||
{
|
||||
for (i = 0; additions[i]; i++)
|
||||
{
|
||||
item = MAKE_STRING (g_strdup (additions[i]));
|
||||
g_ptr_array_insert (self->items, position + i, item);
|
||||
}
|
||||
n_additions = i;
|
||||
GSequenceIter *end;
|
||||
|
||||
end = g_sequence_iter_move (it, n_removals);
|
||||
g_sequence_remove_range (it, end);
|
||||
|
||||
it = end;
|
||||
}
|
||||
else
|
||||
n_additions = 0;
|
||||
|
||||
gtk_bitset_slice (self->objects, position, n_removals, n_additions);
|
||||
if (n_additions)
|
||||
{
|
||||
gint i;
|
||||
|
||||
if (n_removals || n_additions)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, n_additions);
|
||||
for (i = 0; i < n_additions; i++)
|
||||
{
|
||||
g_sequence_insert_before (it, gtk_string_object_new (additions[i]));
|
||||
}
|
||||
}
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, n_additions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -576,13 +522,11 @@ gtk_string_list_append (GtkStringList *self,
|
||||
const char *string)
|
||||
{
|
||||
guint n_items;
|
||||
gpointer item;
|
||||
|
||||
g_return_if_fail (GTK_IS_STRING_LIST (self));
|
||||
|
||||
n_items = self->items->len;
|
||||
item = MAKE_STRING (g_strdup (string));
|
||||
g_ptr_array_add (self->items, item);
|
||||
n_items = g_sequence_get_length (self->items);
|
||||
g_sequence_append (self->items, gtk_string_object_new (string));
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), n_items, 0, 1);
|
||||
}
|
||||
@@ -607,13 +551,11 @@ gtk_string_list_take (GtkStringList *self,
|
||||
char *string)
|
||||
{
|
||||
guint n_items;
|
||||
gpointer item;
|
||||
|
||||
g_return_if_fail (GTK_IS_STRING_LIST (self));
|
||||
|
||||
n_items = self->items->len;
|
||||
item = MAKE_STRING (string);
|
||||
g_ptr_array_add (self->items, item);
|
||||
n_items = g_sequence_get_length (self->items);
|
||||
g_sequence_append (self->items, gtk_string_object_new_take (string));
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), n_items, 0, 1);
|
||||
}
|
||||
@@ -630,13 +572,14 @@ void
|
||||
gtk_string_list_remove (GtkStringList *self,
|
||||
guint position)
|
||||
{
|
||||
GSequenceIter *iter;
|
||||
|
||||
g_return_if_fail (GTK_IS_STRING_LIST (self));
|
||||
|
||||
if (position >= self->items->len)
|
||||
return;
|
||||
iter = g_sequence_get_iter_at_pos (self->items, position);
|
||||
g_return_if_fail (!g_sequence_iter_is_end (iter));
|
||||
|
||||
g_ptr_array_remove_index (self->items, position);
|
||||
gtk_bitset_slice (self->objects, position, 1, 0);
|
||||
g_sequence_remove (iter);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
|
||||
}
|
||||
@@ -646,8 +589,8 @@ gtk_string_list_remove (GtkStringList *self,
|
||||
* @self: a #GtkStringList
|
||||
* @position: the position to get the string for
|
||||
*
|
||||
* Gets the string that is at @position in @self. If @self
|
||||
* does not contain @position items, %NULL is returned.
|
||||
* Gets the string that is at @position in @self. @position
|
||||
* must be smaller than the current length of the list.
|
||||
*
|
||||
* This function returns the const char *. To get the
|
||||
* object wrapping it, use g_list_model_get_item().
|
||||
@@ -658,14 +601,20 @@ const char *
|
||||
gtk_string_list_get_string (GtkStringList *self,
|
||||
guint position)
|
||||
{
|
||||
gpointer item;
|
||||
GSequenceIter *iter;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STRING_LIST (self), NULL);
|
||||
|
||||
item = g_ptr_array_index (self->items, position);
|
||||
iter = g_sequence_get_iter_at_pos (self->items, position);
|
||||
|
||||
if (IS_STRING (item))
|
||||
return (const char *)TO_STRING (item);
|
||||
if (g_sequence_iter_is_end (iter))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return GTK_STRING_OBJECT (item)->string;
|
||||
{
|
||||
GtkStringObject *obj = g_sequence_get (iter);
|
||||
|
||||
return obj->string;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-13
@@ -45,29 +45,30 @@ GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkStringList, gtk_string_list, GTK, STRING_LIST, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkStringList * gtk_string_list_new (const char * const *strings);
|
||||
GtkStringList * gtk_string_list_new (const char **strings);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_string_list_append (GtkStringList *self,
|
||||
const char *string);
|
||||
void gtk_string_list_append (GtkStringList *self,
|
||||
const char *string);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_string_list_take (GtkStringList *self,
|
||||
char *string);
|
||||
void gtk_string_list_take (GtkStringList *self,
|
||||
char *string);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_string_list_remove (GtkStringList *self,
|
||||
guint position);
|
||||
void gtk_string_list_remove (GtkStringList *self,
|
||||
guint position);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_string_list_splice (GtkStringList *self,
|
||||
guint position,
|
||||
guint n_removals,
|
||||
const char * const *additions);
|
||||
void gtk_string_list_splice (GtkStringList *self,
|
||||
guint position,
|
||||
guint n_removals,
|
||||
const char **additions,
|
||||
guint n_additions);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gtk_string_list_get_string (GtkStringList *self,
|
||||
guint position);
|
||||
const char * gtk_string_list_get_string (GtkStringList *self,
|
||||
guint position);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+20
-72
@@ -111,27 +111,13 @@ struct _GtkTextLayoutPrivate
|
||||
GtkTextLineDisplayCache *cache;
|
||||
};
|
||||
|
||||
static GtkTextLineData *gtk_text_layout_real_wrap (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
/* may be NULL */
|
||||
GtkTextLineData *line_data);
|
||||
|
||||
static void gtk_text_layout_invalidated (GtkTextLayout *layout);
|
||||
|
||||
static void gtk_text_layout_real_invalidate (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end);
|
||||
static void gtk_text_layout_real_invalidate_cursors(GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end);
|
||||
static void gtk_text_layout_invalidate_cache (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
gboolean cursors_only);
|
||||
static void gtk_text_layout_invalidate_cursor_line (GtkTextLayout *layout,
|
||||
gboolean cursors_only);
|
||||
static void gtk_text_layout_real_free_line_data (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data);
|
||||
static void gtk_text_layout_emit_changed (GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint old_height,
|
||||
@@ -249,16 +235,11 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
|
||||
object_class->dispose = gtk_text_layout_dispose;
|
||||
object_class->finalize = gtk_text_layout_finalize;
|
||||
|
||||
klass->wrap = gtk_text_layout_real_wrap;
|
||||
klass->invalidate = gtk_text_layout_real_invalidate;
|
||||
klass->invalidate_cursors = gtk_text_layout_real_invalidate_cursors;
|
||||
klass->free_line_data = gtk_text_layout_real_free_line_data;
|
||||
|
||||
signals[INVALIDATED] =
|
||||
g_signal_new (I_("invalidated"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkTextLayoutClass, invalidated),
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
@@ -268,7 +249,7 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
|
||||
g_signal_new (I_("changed"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkTextLayoutClass, changed),
|
||||
0,
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__INT_INT_INT,
|
||||
G_TYPE_NONE,
|
||||
@@ -283,7 +264,7 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
|
||||
g_signal_new (I_("allocate-child"),
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkTextLayoutClass, allocate_child),
|
||||
0,
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__OBJECT_INT_INT,
|
||||
G_TYPE_NONE,
|
||||
@@ -690,39 +671,6 @@ gtk_text_layout_cursors_changed (GtkTextLayout *layout,
|
||||
gtk_text_layout_emit_changed (layout, y, old_height, new_height);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_layout_free_line_data (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data)
|
||||
{
|
||||
GTK_TEXT_LAYOUT_GET_CLASS (layout)->free_line_data (layout, line, line_data);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_layout_invalidate (GtkTextLayout *layout,
|
||||
const GtkTextIter *start_index,
|
||||
const GtkTextIter *end_index)
|
||||
{
|
||||
GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate (layout, start_index, end_index);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_text_layout_invalidate_cursors (GtkTextLayout *layout,
|
||||
const GtkTextIter *start_index,
|
||||
const GtkTextIter *end_index)
|
||||
{
|
||||
GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate_cursors (layout, start_index, end_index);
|
||||
}
|
||||
|
||||
GtkTextLineData*
|
||||
gtk_text_layout_wrap (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
/* may be NULL */
|
||||
GtkTextLineData *line_data)
|
||||
{
|
||||
return GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap (layout, line, line_data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gtk_text_layout_get_lines:
|
||||
@@ -892,10 +840,10 @@ gtk_text_layout_update_cursor_line (GtkTextLayout *layout)
|
||||
gtk_text_line_display_cache_set_cursor_line (priv->cache, priv->cursor_line);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_layout_real_invalidate (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end)
|
||||
void
|
||||
gtk_text_layout_invalidate (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end)
|
||||
{
|
||||
GtkTextLine *line;
|
||||
GtkTextLine *last_line;
|
||||
@@ -936,20 +884,20 @@ gtk_text_layout_real_invalidate (GtkTextLayout *layout,
|
||||
gtk_text_layout_invalidated (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_layout_real_invalidate_cursors (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end)
|
||||
void
|
||||
gtk_text_layout_invalidate_cursors (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end)
|
||||
{
|
||||
GtkTextLayoutPrivate *priv = GTK_TEXT_LAYOUT_GET_PRIVATE (layout);
|
||||
gtk_text_line_display_cache_invalidate_range (priv->cache, layout, start, end, TRUE);
|
||||
gtk_text_layout_invalidated (layout);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_layout_real_free_line_data (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data)
|
||||
void
|
||||
gtk_text_layout_free_line_data (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data)
|
||||
{
|
||||
gtk_text_layout_invalidate_cache (layout, line, FALSE);
|
||||
|
||||
@@ -1148,11 +1096,11 @@ gtk_text_layout_validate (GtkTextLayout *layout,
|
||||
}
|
||||
}
|
||||
|
||||
static GtkTextLineData*
|
||||
gtk_text_layout_real_wrap (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
/* may be NULL */
|
||||
GtkTextLineData *line_data)
|
||||
GtkTextLineData *
|
||||
gtk_text_layout_wrap (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
/* may be NULL */
|
||||
GtkTextLineData *line_data)
|
||||
{
|
||||
GtkTextLineDisplay *display;
|
||||
PangoRectangle ink_rect, logical_rect;
|
||||
|
||||
@@ -167,44 +167,6 @@ struct _GtkTextLayout
|
||||
struct _GtkTextLayoutClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Some portion of the layout was invalidated
|
||||
*/
|
||||
void (*invalidated) (GtkTextLayout *layout);
|
||||
|
||||
/* A range of the layout changed appearance and possibly height
|
||||
*/
|
||||
void (*changed) (GtkTextLayout *layout,
|
||||
gint y,
|
||||
gint old_height,
|
||||
gint new_height);
|
||||
GtkTextLineData* (*wrap) (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data); /* may be NULL */
|
||||
void (*get_log_attrs) (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
PangoLogAttr **attrs,
|
||||
gint *n_attrs);
|
||||
void (*invalidate) (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end);
|
||||
void (*free_line_data) (GtkTextLayout *layout,
|
||||
GtkTextLine *line,
|
||||
GtkTextLineData *line_data);
|
||||
|
||||
void (*allocate_child) (GtkTextLayout *layout,
|
||||
GtkWidget *child,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
void (*invalidate_cursors) (GtkTextLayout *layout,
|
||||
const GtkTextIter *start,
|
||||
const GtkTextIter *end);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
};
|
||||
|
||||
struct _GtkTextAttrAppearance
|
||||
|
||||
@@ -143,7 +143,6 @@
|
||||
#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->priv->text_window)
|
||||
|
||||
#define SPACE_FOR_CURSOR 1
|
||||
#define CURSOR_ASPECT_RATIO (0.04)
|
||||
|
||||
typedef struct _GtkTextWindow GtkTextWindow;
|
||||
typedef struct _GtkTextPendingScroll GtkTextPendingScroll;
|
||||
|
||||
+2
-2
@@ -7377,14 +7377,14 @@ static void
|
||||
gtk_widget_real_realize (GtkWidget *widget)
|
||||
{
|
||||
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
|
||||
GdkFrameClock *frame_clock;
|
||||
|
||||
priv->realized = TRUE;
|
||||
|
||||
/* Connect frame clock */
|
||||
frame_clock = gtk_widget_get_frame_clock (widget);
|
||||
if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
|
||||
{
|
||||
GdkFrameClock *frame_clock = gtk_widget_get_frame_clock (widget);
|
||||
|
||||
priv->clock_tick_id = g_signal_connect (frame_clock, "update",
|
||||
G_CALLBACK (gtk_widget_on_frame_clock_update),
|
||||
widget);
|
||||
|
||||
@@ -4308,7 +4308,6 @@ gtk_window_realize (GtkWidget *widget)
|
||||
if (priv->title_box == NULL)
|
||||
{
|
||||
priv->titlebar = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (priv->titlebar), TRUE);
|
||||
gtk_widget_add_css_class (priv->titlebar, GTK_STYLE_CLASS_TITLEBAR);
|
||||
gtk_widget_add_css_class (priv->titlebar, "default-decoration");
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ setup_parameter_cb (GtkSignalListItemFactory *factory,
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.5);
|
||||
gtk_list_item_set_child (list_item, label);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -168,7 +168,7 @@ setup_state_cb (GtkSignalListItemFactory *factory,
|
||||
gtk_widget_set_margin_end (label, 5);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_list_item_set_child (list_item, label);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -215,7 +215,7 @@ bind_changes_cb (GtkSignalListItemFactory *factory,
|
||||
name = action_holder_get_name (ACTION_HOLDER (item));
|
||||
|
||||
editor = gtk_inspector_action_editor_new (group, name, NULL);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (editor), "cell");
|
||||
gtk_widget_add_css_class (editor, "cell");
|
||||
gtk_list_item_set_child (list_item, editor);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 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 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _GTK_INSPECTOR_DATA_LIST_H_
|
||||
#define _GTK_INSPECTOR_DATA_LIST_H_
|
||||
|
||||
#include <gtk/gtkbox.h>
|
||||
|
||||
#define GTK_TYPE_INSPECTOR_DATA_LIST (gtk_inspector_data_list_get_type())
|
||||
#define GTK_INSPECTOR_DATA_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_DATA_LIST, GtkInspectorDataList))
|
||||
#define GTK_INSPECTOR_DATA_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_DATA_LIST, GtkInspectorDataListClass))
|
||||
#define GTK_INSPECTOR_IS_DATA_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_DATA_LIST))
|
||||
#define GTK_INSPECTOR_IS_DATA_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_DATA_LIST))
|
||||
#define GTK_INSPECTOR_DATA_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_DATA_LIST, GtkInspectorDataListClass))
|
||||
|
||||
|
||||
typedef struct _GtkInspectorDataListPrivate GtkInspectorDataListPrivate;
|
||||
|
||||
typedef struct _GtkInspectorDataList
|
||||
{
|
||||
GtkBox parent;
|
||||
GtkInspectorDataListPrivate *priv;
|
||||
} GtkInspectorDataList;
|
||||
|
||||
typedef struct _GtkInspectorDataListClass
|
||||
{
|
||||
GtkBoxClass parent;
|
||||
} GtkInspectorDataListClass;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gtk_inspector_data_list_get_type (void);
|
||||
void gtk_inspector_data_list_set_object (GtkInspectorDataList *sl,
|
||||
GObject *object);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GTK_INSPECTOR_DATA_LIST_H_
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
@@ -728,6 +728,7 @@
|
||||
<widgets>
|
||||
<widget name="version_frame"/>
|
||||
<widget name="gl_frame"/>
|
||||
<widget name="monitor_frame"/>
|
||||
<widget name="vulkan_frame"/>
|
||||
<widget name="env_frame"/>
|
||||
<widget name="display_frame"/>
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
#include "controllers.h"
|
||||
#include "css-editor.h"
|
||||
#include "css-node-tree.h"
|
||||
#include "data-list.h"
|
||||
#include "general.h"
|
||||
#include "graphdata.h"
|
||||
#include "list-data.h"
|
||||
#include "logs.h"
|
||||
#include "magnifier.h"
|
||||
#include "menu.h"
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "shortcuts.h"
|
||||
#include "size-groups.h"
|
||||
#include "statistics.h"
|
||||
#include "tree-data.h"
|
||||
#include "visual.h"
|
||||
#include "window.h"
|
||||
|
||||
@@ -64,8 +65,8 @@ gtk_inspector_init (void)
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_CONTROLLERS);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_CSS_EDITOR);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_CSS_NODE_TREE);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_DATA_LIST);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_GENERAL);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_LIST_DATA);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_LOGS);
|
||||
g_type_ensure (GTK_TYPE_MAGNIFIER);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_MAGNIFIER);
|
||||
@@ -78,6 +79,7 @@ gtk_inspector_init (void)
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_SHORTCUTS);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_SIZE_GROUPS);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_STATISTICS);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_TREE_DATA);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_VISUAL);
|
||||
g_type_ensure (GTK_TYPE_INSPECTOR_WINDOW);
|
||||
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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 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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "list-data.h"
|
||||
|
||||
#include "object-tree.h"
|
||||
|
||||
#include "gtkcolumnview.h"
|
||||
#include "gtktogglebutton.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkstack.h"
|
||||
#include "gtkboxlayout.h"
|
||||
#include "gtkorientable.h"
|
||||
#include "gtknoselection.h"
|
||||
#include "gtksignallistitemfactory.h"
|
||||
#include "gtklistitem.h"
|
||||
|
||||
|
||||
struct _GtkInspectorListData
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkInspectorObjectTree *object_tree;
|
||||
GListModel *object;
|
||||
GtkColumnView *view;
|
||||
GtkWidget *items_label;
|
||||
};
|
||||
|
||||
struct _GtkInspectorListDataClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_OBJECT_TREE,
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkInspectorListData, gtk_inspector_list_data, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
gtk_inspector_list_data_init (GtkInspectorListData *sl)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (sl));
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (gtk_widget_get_layout_manager (GTK_WIDGET (sl))),
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_inspector_list_data_set_object (GtkInspectorListData *sl,
|
||||
GObject *object)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
GtkStackPage *page;
|
||||
char *text;
|
||||
GtkNoSelection *selection;
|
||||
|
||||
stack = gtk_widget_get_parent (GTK_WIDGET (sl));
|
||||
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl));
|
||||
|
||||
gtk_column_view_set_model (sl->view, NULL);
|
||||
sl->object = NULL;
|
||||
|
||||
if (!G_IS_LIST_MODEL (object))
|
||||
{
|
||||
g_object_set (page, "visible", FALSE, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
text = g_strdup_printf ("%u items", g_list_model_get_n_items (G_LIST_MODEL (object)));
|
||||
gtk_label_set_label (GTK_LABEL (sl->items_label), text);
|
||||
g_free (text);
|
||||
|
||||
g_object_set (page, "visible", TRUE, NULL);
|
||||
|
||||
sl->object = G_LIST_MODEL (object);
|
||||
selection = gtk_no_selection_new (sl->object);
|
||||
gtk_column_view_set_model (sl->view, G_LIST_MODEL (selection));
|
||||
g_object_unref (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_object (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_object (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
gpointer obj;
|
||||
char *text;
|
||||
|
||||
label = gtk_list_item_get_child (item);
|
||||
obj = gtk_list_item_get_item (item);
|
||||
|
||||
text = g_strdup_printf ("%p", obj);
|
||||
gtk_label_set_label (GTK_LABEL (label), text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_type (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
gtk_list_item_set_child (item, label);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_type (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *label;
|
||||
gpointer obj;
|
||||
|
||||
label = gtk_list_item_get_child (item);
|
||||
obj = gtk_list_item_get_item (item);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (label), G_OBJECT_TYPE_NAME (obj));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_props (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkWidget *button;
|
||||
|
||||
button = gtk_button_new_with_label ("Properties");
|
||||
gtk_widget_add_css_class (button, "cell");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_START);
|
||||
gtk_list_item_set_child (item, button);
|
||||
}
|
||||
|
||||
static void
|
||||
object_properties (GtkWidget *button,
|
||||
GtkListItem *item)
|
||||
{
|
||||
GtkInspectorListData *sl;
|
||||
gpointer obj;
|
||||
|
||||
sl = GTK_INSPECTOR_LIST_DATA (gtk_widget_get_ancestor (button, GTK_TYPE_INSPECTOR_LIST_DATA));
|
||||
obj = gtk_list_item_get_item (item);
|
||||
g_object_set_data (G_OBJECT (sl->object_tree), "next-tab", (gpointer)"properties");
|
||||
gtk_inspector_object_tree_activate_object (sl->object_tree, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
bind_props (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item,
|
||||
GtkInspectorListData *sl)
|
||||
{
|
||||
g_signal_connect (gtk_list_item_get_child (item), "clicked",
|
||||
G_CALLBACK (object_properties), item);
|
||||
}
|
||||
|
||||
static void
|
||||
unbind_props (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *item)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (gtk_list_item_get_child (item), object_properties, item);
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkInspectorListData *sl = GTK_INSPECTOR_LIST_DATA (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_OBJECT_TREE:
|
||||
g_value_take_object (value, sl->object_tree);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkInspectorListData *sl = GTK_INSPECTOR_LIST_DATA (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_OBJECT_TREE:
|
||||
sl->object_tree = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
GtkInspectorListData *sl = GTK_INSPECTOR_LIST_DATA (object);
|
||||
|
||||
gtk_inspector_list_data_set_object (sl, NULL);
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_list_data_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_list_data_class_init (GtkInspectorListDataClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->finalize = finalize;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_OBJECT_TREE,
|
||||
g_param_spec_object ("object-tree", "Object Tree", "Object tree",
|
||||
GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/list-data.ui");
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorListData, view);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorListData, items_label);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, setup_object);
|
||||
gtk_widget_class_bind_template_callback (widget_class, bind_object);
|
||||
gtk_widget_class_bind_template_callback (widget_class, setup_type);
|
||||
gtk_widget_class_bind_template_callback (widget_class, bind_type);
|
||||
gtk_widget_class_bind_template_callback (widget_class, setup_props);
|
||||
gtk_widget_class_bind_template_callback (widget_class, bind_props);
|
||||
gtk_widget_class_bind_template_callback (widget_class, unbind_props);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
|
||||
}
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _GTK_INSPECTOR_LIST_DATA_H_
|
||||
#define _GTK_INSPECTOR_LIST_DATA_H_
|
||||
|
||||
#include <gtk/gtkbox.h>
|
||||
|
||||
#define GTK_TYPE_INSPECTOR_LIST_DATA (gtk_inspector_list_data_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkInspectorListData, gtk_inspector_list_data, GTK, INSPECTOR_LIST_DATA, GtkWidget)
|
||||
|
||||
typedef struct _GtkInspectorListData GtkInspectorListData;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_inspector_list_data_set_object (GtkInspectorListData *sl,
|
||||
GObject *object);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GTK_INSPECTOR_LIST_DATA_H_
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
@@ -0,0 +1,68 @@
|
||||
<interface domain="gtk40">
|
||||
<template class="GtkInspectorListData" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">6</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin-end">6</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="items_label">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">end</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="vscrollbar-policy">always</property>
|
||||
<child>
|
||||
<object class="GtkColumnView" id="view">
|
||||
<style>
|
||||
<class name="list"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title">Object</property>
|
||||
<property name="factory">
|
||||
<object class="GtkSignalListItemFactory">
|
||||
<signal name="setup" handler="setup_object"/>
|
||||
<signal name="bind" handler="bind_object"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title">Type</property>
|
||||
<property name="factory">
|
||||
<object class="GtkSignalListItemFactory">
|
||||
<signal name="setup" handler="setup_type"/>
|
||||
<signal name="bind" handler="bind_type"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title"></property>
|
||||
<property name="expand">1</property>
|
||||
<property name="factory">
|
||||
<object class="GtkSignalListItemFactory">
|
||||
<signal name="setup" handler="setup_props"/>
|
||||
<signal name="bind" handler="bind_props"/>
|
||||
<signal name="unbind" handler="unbind_props"/>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -6,7 +6,6 @@ inspector_sources = files(
|
||||
'controllers.c',
|
||||
'css-editor.c',
|
||||
'css-node-tree.c',
|
||||
'data-list.c',
|
||||
'focusoverlay.c',
|
||||
'fpsoverlay.c',
|
||||
'general.c',
|
||||
@@ -16,6 +15,7 @@ inspector_sources = files(
|
||||
'init.c',
|
||||
'inspect-button.c',
|
||||
'inspectoroverlay.c',
|
||||
'list-data.c',
|
||||
'layoutoverlay.c',
|
||||
'logs.c',
|
||||
'magnifier.c',
|
||||
@@ -33,6 +33,7 @@ inspector_sources = files(
|
||||
'startrecording.c',
|
||||
'statistics.c',
|
||||
'strv-editor.c',
|
||||
'tree-data.c',
|
||||
'treewalk.c',
|
||||
'type-info.c',
|
||||
'updatesoverlay.c',
|
||||
|
||||
@@ -769,36 +769,6 @@ font_changed (GObject *object, GParamSpec *pspec, gpointer data)
|
||||
pango_font_description_free (fb_font_desc);
|
||||
}
|
||||
|
||||
static void
|
||||
item_properties (GtkButton *button, GtkInspectorPropEditor *self)
|
||||
{
|
||||
GObject *item;
|
||||
item = g_object_get_data (G_OBJECT (button), "item");
|
||||
g_signal_emit (self, signals[SHOW_OBJECT], 0, item, "Item", "properties");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_row (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *row, *label, *button;
|
||||
char *name;
|
||||
|
||||
name = object_label (G_OBJECT (item), NULL);
|
||||
label = gtk_label_new (name);
|
||||
g_free (name);
|
||||
|
||||
button = gtk_button_new_with_label (_("Properties"));
|
||||
g_object_set_data (G_OBJECT (button), "item", item);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (item_properties), user_data);
|
||||
|
||||
row = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
|
||||
gtk_box_append (GTK_BOX (row), label);
|
||||
gtk_box_append (GTK_BOX (row), button);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
property_editor (GObject *object,
|
||||
GParamSpec *spec,
|
||||
@@ -1003,39 +973,6 @@ property_editor (GObject *object,
|
||||
G_CALLBACK (pointer_changed),
|
||||
prop_edit, G_OBJECT (prop_edit));
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_OBJECT &&
|
||||
g_type_is_a (G_PARAM_SPEC_VALUE_TYPE (spec), G_TYPE_LIST_MODEL))
|
||||
{
|
||||
GtkWidget *popover;
|
||||
GtkWidget *box;
|
||||
GtkWidget *sw;
|
||||
GListModel *model;
|
||||
|
||||
popover = gtk_popover_new ();
|
||||
prop_edit = gtk_menu_button_new ();
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (prop_edit), popover);
|
||||
|
||||
sw = gtk_scrolled_window_new ();
|
||||
gtk_popover_set_child (GTK_POPOVER (popover), sw);
|
||||
g_object_set (sw,
|
||||
"hexpand", TRUE,
|
||||
"vexpand", TRUE,
|
||||
"hscrollbar-policy", GTK_POLICY_NEVER,
|
||||
"vscrollbar-policy", GTK_POLICY_NEVER,
|
||||
NULL);
|
||||
|
||||
g_object_get (object, spec->name, &model, NULL);
|
||||
|
||||
if (g_list_model_get_n_items (model) >= 10)
|
||||
g_object_set (prop_edit, "vscrollbar-policy", GTK_POLICY_AUTOMATIC, NULL);
|
||||
|
||||
box = gtk_list_box_new ();
|
||||
gtk_list_box_set_selection_mode (GTK_LIST_BOX (box), GTK_SELECTION_NONE);
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (box), model, create_row, self, NULL);
|
||||
g_object_unref (model);
|
||||
|
||||
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), box);
|
||||
}
|
||||
else if (type == G_TYPE_PARAM_OBJECT)
|
||||
{
|
||||
GtkWidget *label, *button;
|
||||
|
||||
@@ -314,7 +314,7 @@ setup_name_cb (GtkSignalListItemFactory *factory,
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_list_item_set_child (list_item, label);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -339,7 +339,7 @@ setup_type_cb (GtkSignalListItemFactory *factory,
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_list_item_set_child (list_item, label);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -369,7 +369,7 @@ setup_origin_cb (GtkSignalListItemFactory *factory,
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_list_item_set_child (list_item, label);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_widget_add_css_class (label, "cell");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -408,7 +408,7 @@ bind_value_cb (GtkSignalListItemFactory *factory,
|
||||
widget = gtk_inspector_prop_editor_new (object, name, NULL);
|
||||
g_signal_connect (widget, "show-object", G_CALLBACK (show_object), data);
|
||||
gtk_list_item_set_child (list_item, widget);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "cell");
|
||||
gtk_widget_add_css_class (widget, "cell");
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+17
-83
@@ -22,9 +22,10 @@
|
||||
#include <gtk/gtkbinlayout.h>
|
||||
#include <gtk/gtkbox.h>
|
||||
#include <gtk/gtkfilechooserdialog.h>
|
||||
#include <gtk/gtkfunctionslistitemfactory.h>
|
||||
#include <gtk/gtksignallistitemfactory.h>
|
||||
#include <gtk/gtklabel.h>
|
||||
#include <gtk/gtklistbox.h>
|
||||
#include <gtk/gtklistitem.h>
|
||||
#include <gtk/gtklistview.h>
|
||||
#include <gtk/gtkliststore.h>
|
||||
#include <gtk/gtkmessagedialog.h>
|
||||
@@ -302,8 +303,8 @@ node_name (GskRenderNode *node)
|
||||
}
|
||||
|
||||
static void
|
||||
setup_widget_for_render_node (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
setup_widget_for_render_node (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *expander, *box, *child;
|
||||
|
||||
@@ -324,8 +325,8 @@ setup_widget_for_render_node (GtkListItem *list_item,
|
||||
}
|
||||
|
||||
static void
|
||||
bind_widget_for_render_node (GtkListItem *list_item,
|
||||
gpointer unused)
|
||||
bind_widget_for_render_node (GtkSignalListItemFactory *factory,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
GskRenderNode *node;
|
||||
@@ -384,8 +385,6 @@ recordings_list_row_selected (GtkListBox *box,
|
||||
(gpointer[1]) { paintable },
|
||||
1);
|
||||
g_object_unref (paintable);
|
||||
|
||||
g_print ("%u render nodes\n", g_list_model_get_n_items (G_LIST_MODEL (priv->render_node_model)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -404,9 +403,9 @@ get_color_texture (const GdkRGBA *color)
|
||||
guchar pixel[4];
|
||||
guchar *data;
|
||||
GBytes *bytes;
|
||||
gint width = 30;
|
||||
gint height = 30;
|
||||
gint i;
|
||||
int width = 30;
|
||||
int height = 30;
|
||||
int i;
|
||||
|
||||
pixel[0] = round (color->red * 255);
|
||||
pixel[1] = round (color->green * 255);
|
||||
@@ -949,7 +948,7 @@ render_node_list_selection_changed (GtkListBox *list,
|
||||
|
||||
static void
|
||||
render_node_save_response (GtkWidget *dialog,
|
||||
gint response,
|
||||
int response,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
gtk_widget_hide (dialog);
|
||||
@@ -1018,83 +1017,33 @@ render_node_save (GtkButton *button,
|
||||
gtk_widget_show (dialog);
|
||||
}
|
||||
|
||||
static char *
|
||||
format_timespan (gint64 timespan)
|
||||
{
|
||||
if (ABS (timespan) < G_TIME_SPAN_MILLISECOND)
|
||||
return g_strdup_printf ("%fus", (double) timespan);
|
||||
else if (ABS (timespan) < 10 * G_TIME_SPAN_MILLISECOND)
|
||||
return g_strdup_printf ("%.1fs", (double) timespan / G_TIME_SPAN_MILLISECOND);
|
||||
else if (ABS (timespan) < G_TIME_SPAN_SECOND)
|
||||
return g_strdup_printf ("%.0fms", (double) timespan / G_TIME_SPAN_MILLISECOND);
|
||||
else if (ABS (timespan) < 10 * G_TIME_SPAN_SECOND)
|
||||
return g_strdup_printf ("%.1fs", (double) timespan / G_TIME_SPAN_SECOND);
|
||||
else
|
||||
return g_strdup_printf ("%.0fs", (double) timespan / G_TIME_SPAN_SECOND);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
gtk_inspector_recorder_recordings_list_create_widget (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkInspectorRecorder *recorder = GTK_INSPECTOR_RECORDER (user_data);
|
||||
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
|
||||
GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (item);
|
||||
GtkWidget *widget;
|
||||
|
||||
if (GTK_INSPECTOR_IS_RENDER_RECORDING (recording))
|
||||
{
|
||||
GtkInspectorRecording *previous = NULL;
|
||||
char *time_str, *str;
|
||||
const char *render_str;
|
||||
cairo_region_t *region;
|
||||
GtkWidget *hbox, *label, *button;
|
||||
guint i;
|
||||
|
||||
widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
gtk_box_append (GTK_BOX (widget), hbox);
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (priv->recordings); i++)
|
||||
{
|
||||
GtkInspectorRecording *r = g_list_model_get_item (priv->recordings, i);
|
||||
|
||||
g_object_unref (r);
|
||||
|
||||
if (r == recording)
|
||||
break;
|
||||
|
||||
if (GTK_INSPECTOR_IS_RENDER_RECORDING (r))
|
||||
previous = r;
|
||||
else if (GTK_INSPECTOR_IS_START_RECORDING (r))
|
||||
previous = NULL;
|
||||
}
|
||||
|
||||
region = cairo_region_create_rectangle (
|
||||
gtk_inspector_render_recording_get_area (GTK_INSPECTOR_RENDER_RECORDING (recording)));
|
||||
cairo_region_subtract (region,
|
||||
gtk_inspector_render_recording_get_clip_region (GTK_INSPECTOR_RENDER_RECORDING (recording)));
|
||||
if (cairo_region_is_empty (region))
|
||||
render_str = "Full Render";
|
||||
else
|
||||
render_str = "Partial Render";
|
||||
cairo_region_destroy (region);
|
||||
|
||||
if (previous)
|
||||
{
|
||||
time_str = format_timespan (gtk_inspector_recording_get_timestamp (recording) -
|
||||
gtk_inspector_recording_get_timestamp (previous));
|
||||
str = g_strdup_printf ("<b>%s</b>\n+%s", render_str, time_str);
|
||||
g_free (time_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
str = g_strdup_printf ("<b>%s</b>\n", render_str);
|
||||
}
|
||||
label = gtk_label_new (str);
|
||||
label = gtk_label_new ("<b>Frame</b>");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
g_free (str);
|
||||
gtk_box_append (GTK_BOX (hbox), label);
|
||||
|
||||
button = gtk_toggle_button_new ();
|
||||
@@ -1291,9 +1240,10 @@ gtk_inspector_recorder_init (GtkInspectorRecorder *recorder)
|
||||
priv->render_node_selection = gtk_single_selection_new (G_LIST_MODEL (priv->render_node_model));
|
||||
g_signal_connect (priv->render_node_selection, "notify::selected-item", G_CALLBACK (render_node_list_selection_changed), recorder);
|
||||
|
||||
factory = gtk_functions_list_item_factory_new (setup_widget_for_render_node,
|
||||
bind_widget_for_render_node,
|
||||
NULL, NULL);
|
||||
factory = gtk_signal_list_item_factory_new ();
|
||||
g_signal_connect (factory, "setup", G_CALLBACK (setup_widget_for_render_node), NULL);
|
||||
g_signal_connect (factory, "bind", G_CALLBACK (bind_widget_for_render_node), NULL);
|
||||
|
||||
gtk_list_view_set_factory (GTK_LIST_VIEW (priv->render_node_list), factory);
|
||||
g_object_unref (factory);
|
||||
gtk_list_view_set_model (GTK_LIST_VIEW (priv->render_node_list),
|
||||
@@ -1309,24 +1259,8 @@ gtk_inspector_recorder_add_recording (GtkInspectorRecorder *recorder,
|
||||
GtkInspectorRecording *recording)
|
||||
{
|
||||
GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
|
||||
guint count;
|
||||
GtkListBoxRow *selected_row;
|
||||
gboolean should_select_new_row;
|
||||
|
||||
count = g_list_model_get_n_items (priv->recordings);
|
||||
selected_row = gtk_list_box_get_selected_row (GTK_LIST_BOX (priv->recordings_list));
|
||||
if (count == 0 || selected_row == NULL)
|
||||
should_select_new_row = TRUE;
|
||||
else
|
||||
should_select_new_row = (gtk_list_box_row_get_index (selected_row) == count - 1);
|
||||
|
||||
g_list_store_append (G_LIST_STORE (priv->recordings), recording);
|
||||
|
||||
if (should_select_new_row)
|
||||
{
|
||||
gtk_list_box_select_row (GTK_LIST_BOX (priv->recordings_list),
|
||||
gtk_list_box_get_row_at_index (GTK_LIST_BOX (priv->recordings_list), count));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Red Hat, Inc.
|
||||
* Copyright (c) 2014, 2020 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
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "config.h"
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "data-list.h"
|
||||
#include "tree-data.h"
|
||||
|
||||
#include "object-tree.h"
|
||||
|
||||
@@ -27,10 +27,14 @@
|
||||
#include "gtktogglebutton.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkstack.h"
|
||||
#include "gtkboxlayout.h"
|
||||
#include "gtkorientable.h"
|
||||
|
||||
|
||||
struct _GtkInspectorDataListPrivate
|
||||
struct _GtkInspectorTreeData
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkTreeModel *object;
|
||||
GtkTreeModel *types;
|
||||
GtkTreeView *view;
|
||||
@@ -38,13 +42,22 @@ struct _GtkInspectorDataListPrivate
|
||||
gboolean show_data;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorDataList, gtk_inspector_data_list, GTK_TYPE_BOX)
|
||||
typedef struct _GtkInspectorTreeDataClass GtkInspectorTreeDataClass;
|
||||
struct _GtkInspectorTreeDataClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GtkInspectorTreeData, gtk_inspector_tree_data, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
gtk_inspector_data_list_init (GtkInspectorDataList *sl)
|
||||
gtk_inspector_tree_data_init (GtkInspectorTreeData *sl)
|
||||
{
|
||||
sl->priv = gtk_inspector_data_list_get_instance_private (sl);
|
||||
gtk_widget_init_template (GTK_WIDGET (sl));
|
||||
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (gtk_widget_get_layout_manager (GTK_WIDGET (sl))),
|
||||
GTK_ORIENTATION_VERTICAL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -67,7 +80,7 @@ cell_data_func (GtkTreeViewColumn *col,
|
||||
}
|
||||
|
||||
static void
|
||||
add_columns (GtkInspectorDataList *sl)
|
||||
add_columns (GtkInspectorTreeData *sl)
|
||||
{
|
||||
gint n_columns;
|
||||
GtkCellRenderer *cell;
|
||||
@@ -76,45 +89,45 @@ add_columns (GtkInspectorDataList *sl)
|
||||
GtkTreeViewColumn *col;
|
||||
gint i;
|
||||
|
||||
n_columns = gtk_tree_model_get_n_columns (sl->priv->object);
|
||||
n_columns = gtk_tree_model_get_n_columns (sl->object);
|
||||
for (i = 0; i < n_columns; i++)
|
||||
{
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
type = gtk_tree_model_get_column_type (sl->priv->object, i);
|
||||
type = gtk_tree_model_get_column_type (sl->object, i);
|
||||
title = g_strdup_printf ("%d: %s", i, g_type_name (type));
|
||||
col = gtk_tree_view_column_new_with_attributes (title, cell, NULL);
|
||||
g_object_set_data (G_OBJECT (col), "num", GINT_TO_POINTER (i));
|
||||
gtk_tree_view_column_set_cell_data_func (col, cell, cell_data_func, sl, NULL);
|
||||
gtk_tree_view_append_column (sl->priv->view, col);
|
||||
gtk_tree_view_append_column (sl->view, col);
|
||||
g_free (title);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_types (GtkInspectorDataList *sl)
|
||||
show_types (GtkInspectorTreeData *sl)
|
||||
{
|
||||
gtk_tree_view_set_model (sl->priv->view, NULL);
|
||||
sl->priv->show_data = FALSE;
|
||||
gtk_tree_view_set_model (sl->view, NULL);
|
||||
sl->show_data = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
show_data (GtkInspectorDataList *sl)
|
||||
show_data (GtkInspectorTreeData *sl)
|
||||
{
|
||||
gtk_tree_view_set_model (sl->priv->view, sl->priv->object);
|
||||
sl->priv->show_data = TRUE;
|
||||
gtk_tree_view_set_model (sl->view, sl->object);
|
||||
sl->show_data = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_view (GtkInspectorDataList *sl)
|
||||
clear_view (GtkInspectorTreeData *sl)
|
||||
{
|
||||
gtk_tree_view_set_model (sl->priv->view, NULL);
|
||||
while (gtk_tree_view_get_n_columns (sl->priv->view) > 0)
|
||||
gtk_tree_view_remove_column (sl->priv->view,
|
||||
gtk_tree_view_get_column (sl->priv->view, 0));
|
||||
gtk_tree_view_set_model (sl->view, NULL);
|
||||
while (gtk_tree_view_get_n_columns (sl->view) > 0)
|
||||
gtk_tree_view_remove_column (sl->view,
|
||||
gtk_tree_view_get_column (sl->view, 0));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_inspector_data_list_set_object (GtkInspectorDataList *sl,
|
||||
gtk_inspector_tree_data_set_object (GtkInspectorTreeData *sl,
|
||||
GObject *object)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
@@ -125,8 +138,8 @@ gtk_inspector_data_list_set_object (GtkInspectorDataList *sl,
|
||||
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl));
|
||||
|
||||
clear_view (sl);
|
||||
sl->priv->object = NULL;
|
||||
sl->priv->show_data = FALSE;
|
||||
sl->object = NULL;
|
||||
sl->show_data = FALSE;
|
||||
|
||||
if (!GTK_IS_TREE_MODEL (object))
|
||||
{
|
||||
@@ -135,21 +148,21 @@ gtk_inspector_data_list_set_object (GtkInspectorDataList *sl,
|
||||
}
|
||||
|
||||
title = gtk_inspector_get_object_title (object);
|
||||
gtk_label_set_label (GTK_LABEL (sl->priv->object_title), title);
|
||||
gtk_label_set_label (GTK_LABEL (sl->object_title), title);
|
||||
g_free (title);
|
||||
|
||||
g_object_set (page, "visible", TRUE, NULL);
|
||||
|
||||
sl->priv->object = GTK_TREE_MODEL (object);
|
||||
sl->object = GTK_TREE_MODEL (object);
|
||||
add_columns (sl);
|
||||
show_types (sl);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_show (GtkToggleButton *button,
|
||||
GtkInspectorDataList *sl)
|
||||
GtkInspectorTreeData *sl)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (button) == sl->priv->show_data)
|
||||
if (gtk_toggle_button_get_active (button) == sl->show_data)
|
||||
return;
|
||||
|
||||
if (gtk_toggle_button_get_active (button))
|
||||
@@ -159,14 +172,16 @@ toggle_show (GtkToggleButton *button,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_data_list_class_init (GtkInspectorDataListClass *klass)
|
||||
gtk_inspector_tree_data_class_init (GtkInspectorTreeDataClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/data-list.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorDataList, view);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorDataList, object_title);
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/tree-data.ui");
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorTreeData, view);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorTreeData, object_title);
|
||||
gtk_widget_class_bind_template_callback (widget_class, toggle_show);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
|
||||
}
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2020 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 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/>.
|
||||
*/
|
||||
|
||||
#ifndef _GTK_INSPECTOR_TREE_DATA_H_
|
||||
#define _GTK_INSPECTOR_TREE_DATA_H_
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
#define GTK_TYPE_INSPECTOR_TREE_DATA (gtk_inspector_tree_data_get_type ())
|
||||
#define GTK_INSPECTOR_TREE_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_TREE_DATA, GtkInspectorTreeData))
|
||||
#define GTK_INSPECTOR_IS_TREE_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_TREE_DATA))
|
||||
|
||||
typedef struct _GtkInspectorTreeData GtkInspectorTreeData;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GType gtk_inspector_tree_data_get_type (void) G_GNUC_CONST;
|
||||
void gtk_inspector_tree_data_set_object (GtkInspectorTreeData *sl,
|
||||
GObject *object);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif // _GTK_INSPECTOR_TREE_DATA_H_
|
||||
|
||||
// vim: set et sw=2 ts=2:
|
||||
@@ -1,6 +1,5 @@
|
||||
<interface domain="gtk40">
|
||||
<template class="GtkInspectorDataList" parent="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<template class="GtkInspectorTreeData" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">6</property>
|
||||
@@ -35,13 +35,14 @@
|
||||
#include "css-node-tree.h"
|
||||
#include "object-tree.h"
|
||||
#include "size-groups.h"
|
||||
#include "data-list.h"
|
||||
#include "actions.h"
|
||||
#include "shortcuts.h"
|
||||
#include "list-data.h"
|
||||
#include "menu.h"
|
||||
#include "misc-info.h"
|
||||
#include "magnifier.h"
|
||||
#include "recorder.h"
|
||||
#include "tree-data.h"
|
||||
#include "visual.h"
|
||||
#include "general.h"
|
||||
#include "logs.h"
|
||||
@@ -100,7 +101,8 @@ set_selected_object (GtkInspectorWindow *iw,
|
||||
gtk_inspector_misc_info_set_object (GTK_INSPECTOR_MISC_INFO (iw->misc_info), selected);
|
||||
gtk_inspector_css_node_tree_set_object (GTK_INSPECTOR_CSS_NODE_TREE (iw->widget_css_node_tree), selected);
|
||||
gtk_inspector_size_groups_set_object (GTK_INSPECTOR_SIZE_GROUPS (iw->size_groups), selected);
|
||||
gtk_inspector_data_list_set_object (GTK_INSPECTOR_DATA_LIST (iw->data_list), selected);
|
||||
gtk_inspector_tree_data_set_object (GTK_INSPECTOR_TREE_DATA (iw->tree_data), selected);
|
||||
gtk_inspector_list_data_set_object (GTK_INSPECTOR_LIST_DATA (iw->list_data), selected);
|
||||
gtk_inspector_actions_set_object (GTK_INSPECTOR_ACTIONS (iw->actions), selected);
|
||||
gtk_inspector_shortcuts_set_object (GTK_INSPECTOR_SHORTCUTS (iw->shortcuts), selected);
|
||||
gtk_inspector_menu_set_object (GTK_INSPECTOR_MENU (iw->menu), selected);
|
||||
@@ -445,7 +447,8 @@ gtk_inspector_window_class_init (GtkInspectorWindowClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, widget_recorder);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, object_title);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, size_groups);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, data_list);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, tree_data);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, list_data);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, actions);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, shortcuts);
|
||||
gtk_widget_class_bind_template_child (widget_class, GtkInspectorWindow, menu);
|
||||
|
||||
@@ -64,7 +64,8 @@ typedef struct
|
||||
GtkWidget *widget_recorder;
|
||||
GtkWidget *object_hierarchy;
|
||||
GtkWidget *size_groups;
|
||||
GtkWidget *data_list;
|
||||
GtkWidget *tree_data;
|
||||
GtkWidget *list_data;
|
||||
GtkWidget *actions;
|
||||
GtkWidget *shortcuts;
|
||||
GtkWidget *menu;
|
||||
|
||||
+12
-2
@@ -12,7 +12,6 @@
|
||||
<property name="default-width">800</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="button_stack">
|
||||
<property name="visible-child-name" bind-source="top_stack" bind-property="visible-child-name"/>
|
||||
@@ -405,7 +404,18 @@
|
||||
<property name="name">data</property>
|
||||
<property name="title" translatable="yes">Data</property>
|
||||
<property name="child">
|
||||
<object class="GtkInspectorDataList" id="data_list"/>
|
||||
<object class="GtkInspectorTreeData" id="tree_data"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">list-data</property>
|
||||
<property name="title" translatable="yes">Data</property>
|
||||
<property name="child">
|
||||
<object class="GtkInspectorListData" id="list_data">
|
||||
<property name="object-tree">object_tree</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
+2
-2
@@ -253,7 +253,6 @@ gtk_public_sources = files([
|
||||
'gtkfontchooserutils.c',
|
||||
'gtkfontchooserwidget.c',
|
||||
'gtkframe.c',
|
||||
'gtkfunctionslistitemfactory.c',
|
||||
'gtkgesture.c',
|
||||
'gtkgesturedrag.c',
|
||||
'gtkgesturelongpress.c',
|
||||
@@ -349,6 +348,7 @@ gtk_public_sources = files([
|
||||
'gtkscrolledwindow.c',
|
||||
'gtksearchbar.c',
|
||||
'gtksearchentry.c',
|
||||
'gtkselectionfiltermodel.c',
|
||||
'gtkselectionmodel.c',
|
||||
'gtkseparator.c',
|
||||
'gtksettings.c',
|
||||
@@ -537,7 +537,6 @@ gtk_public_headers = files([
|
||||
'gtkfontchooserdialog.h',
|
||||
'gtkfontchooserwidget.h',
|
||||
'gtkframe.h',
|
||||
'gtkfunctionslistitemfactory.h',
|
||||
'gtkgesture.h',
|
||||
'gtkgesturedrag.h',
|
||||
'gtkgesturelongpress.h',
|
||||
@@ -619,6 +618,7 @@ gtk_public_headers = files([
|
||||
'gtkscrolledwindow.h',
|
||||
'gtksearchbar.h',
|
||||
'gtksearchentry.h',
|
||||
'gtkselectionfiltermodel.h',
|
||||
'gtkselectionmodel.h',
|
||||
'gtkseparator.h',
|
||||
'gtksettings.h',
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<property name="resizable">0</property>
|
||||
<child internal-child="headerbar">
|
||||
<object class="GtkHeaderBar" id="headerbar1">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="stack_switcher">
|
||||
<property name="visible">0</property>
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
<interface domain="gtk40">
|
||||
<template class="GtkAssistant" parent="GtkWindow">
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="headerbar"/>
|
||||
<object class="GtkHeaderBar" id="headerbar">
|
||||
<property name="show-title-buttons">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_box">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user