2014-11-01 02:28:17 +00:00
|
|
|
#include <string.h>
|
2014-06-24 22:36:29 +00:00
|
|
|
#include "iconbrowserapp.h"
|
|
|
|
#include "iconbrowserwin.h"
|
2020-06-08 18:25:54 +00:00
|
|
|
#include "iconbrowsericon.h"
|
|
|
|
#include "iconbrowsercontext.h"
|
2014-06-24 22:36:29 +00:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2017-06-02 01:52:50 +00:00
|
|
|
|
2014-06-24 22:36:29 +00:00
|
|
|
struct _IconBrowserWindow
|
|
|
|
{
|
|
|
|
GtkApplicationWindow parent;
|
|
|
|
|
2014-07-27 07:32:10 +00:00
|
|
|
GtkWidget *symbolic_radio;
|
2014-06-24 22:36:29 +00:00
|
|
|
GtkWidget *searchbar;
|
2020-06-08 18:25:54 +00:00
|
|
|
GListModel *icon_filter_model;
|
|
|
|
GListStore *icon_store;
|
2021-03-04 21:13:46 +00:00
|
|
|
GListModel *context_model;
|
2020-06-08 18:25:54 +00:00
|
|
|
GListStore *context_store;
|
|
|
|
GtkFilter *name_filter;
|
2021-03-04 21:13:46 +00:00
|
|
|
GtkFilter *search_mode_filter;
|
2020-06-08 18:25:54 +00:00
|
|
|
GtkWidget *details;
|
2014-06-24 22:36:29 +00:00
|
|
|
GtkWidget *image1;
|
|
|
|
GtkWidget *image2;
|
|
|
|
GtkWidget *image3;
|
|
|
|
GtkWidget *image4;
|
|
|
|
GtkWidget *image5;
|
2017-08-07 21:33:42 +00:00
|
|
|
GtkWidget *image6;
|
IconTheme: Simplify icon scaling
We had a pretty complex setup where we tried to avoid scaling up themes from dirs
that specified a size. However, not only was it very complex, but it didn't quite
work with window scales, because when using e.g. a size 32 directory for 16@2x
the dir size is wrong anyway. Additionally it turns out most code either picks
an existing icon size, or uses the FORCE_SIZE flags, so it doesn't seem
like a useful behaviour.
This change drops the FORCE_SIZE flags, and always scales
icons. Additionally it moves the scaling of the icon to rendering,
which seems more modern, and allows us to (later) share icons loaded
for different sizes that happened to use the same source file (at
different scales).
Note that this changes the behaviour of
gtk_icon_paintable_download_texture() is it now returns the unscaled
source icon. However, ignore thats, as I plan to remove this function
and replace it with a way to render a paintable to a cairo-surface
instead.
2020-02-05 14:47:23 +00:00
|
|
|
GtkWidget *image7;
|
|
|
|
GtkWidget *image8;
|
|
|
|
GtkWidget *label8;
|
2014-06-24 22:36:29 +00:00
|
|
|
GtkWidget *description;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _IconBrowserWindowClass
|
|
|
|
{
|
|
|
|
GtkApplicationWindowClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
G_DEFINE_TYPE(IconBrowserWindow, icon_browser_window, GTK_TYPE_APPLICATION_WINDOW);
|
|
|
|
|
2020-02-01 22:38:49 +00:00
|
|
|
static GtkIconTheme *
|
|
|
|
icon_browser_window_get_icon_theme (IconBrowserWindow *win)
|
|
|
|
{
|
|
|
|
return gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (win)));
|
|
|
|
}
|
|
|
|
|
2014-06-24 22:36:29 +00:00
|
|
|
static void
|
|
|
|
add_icon (IconBrowserWindow *win,
|
2020-07-24 18:40:36 +00:00
|
|
|
const char *name,
|
|
|
|
const char *description,
|
|
|
|
const char *context)
|
2014-06-24 22:36:29 +00:00
|
|
|
{
|
2020-02-01 22:38:49 +00:00
|
|
|
GtkIconTheme *icon_theme = icon_browser_window_get_icon_theme (win);
|
2020-07-24 18:40:36 +00:00
|
|
|
char *regular_name;
|
|
|
|
char *symbolic_name;
|
2020-06-08 18:25:54 +00:00
|
|
|
IbIcon *icon;
|
2014-07-27 07:32:10 +00:00
|
|
|
|
|
|
|
regular_name = g_strdup (name);
|
2020-02-01 22:38:49 +00:00
|
|
|
if (!gtk_icon_theme_has_icon (icon_theme, regular_name))
|
2014-07-27 07:32:10 +00:00
|
|
|
{
|
|
|
|
g_free (regular_name);
|
|
|
|
regular_name = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbolic_name = g_strconcat (name, "-symbolic", NULL);
|
2020-02-01 22:38:49 +00:00
|
|
|
if (!gtk_icon_theme_has_icon (icon_theme, symbolic_name))
|
2014-07-27 07:32:10 +00:00
|
|
|
{
|
|
|
|
g_free (symbolic_name);
|
|
|
|
symbolic_name = NULL;
|
|
|
|
}
|
2017-06-02 01:52:50 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
icon = ib_icon_new (regular_name, symbolic_name, description, context);
|
|
|
|
g_object_bind_property (win->symbolic_radio, "active",
|
|
|
|
icon, "use-symbolic",
|
|
|
|
G_BINDING_DEFAULT);
|
|
|
|
g_list_store_append (win->icon_store, icon);
|
|
|
|
g_object_unref (icon);
|
2014-06-24 22:36:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_context (IconBrowserWindow *win,
|
2020-07-24 18:40:36 +00:00
|
|
|
const char *id,
|
|
|
|
const char *name,
|
|
|
|
const char *description)
|
2014-06-24 22:36:29 +00:00
|
|
|
{
|
2020-06-08 18:25:54 +00:00
|
|
|
IbContext *context;
|
2014-08-02 11:55:44 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
context = ib_context_new (id, name, description);
|
|
|
|
g_list_store_append (win->context_store, context);
|
|
|
|
g_object_unref (context);
|
2014-06-24 22:36:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
populate (IconBrowserWindow *win)
|
|
|
|
{
|
2017-06-02 01:52:50 +00:00
|
|
|
GFile *file;
|
|
|
|
GKeyFile *kf;
|
|
|
|
char *data;
|
|
|
|
gsize length;
|
|
|
|
char **groups;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
file = g_file_new_for_uri ("resource:/org/gtk/iconbrowser/gtk/icon.list");
|
|
|
|
g_file_load_contents (file, NULL, &data, &length, NULL, NULL);
|
|
|
|
|
|
|
|
kf = g_key_file_new ();
|
|
|
|
g_key_file_load_from_data (kf, data, length, G_KEY_FILE_NONE, NULL);
|
|
|
|
|
|
|
|
groups = g_key_file_get_groups (kf, &length);
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
{
|
|
|
|
const char *context;
|
|
|
|
const char *name;
|
|
|
|
const char *description;
|
|
|
|
char **keys;
|
|
|
|
gsize len;
|
|
|
|
int j;
|
|
|
|
|
|
|
|
context = groups[i];
|
|
|
|
name = g_key_file_get_string (kf, context, "Name", NULL);
|
|
|
|
description = g_key_file_get_string (kf, context, "Description", NULL);
|
|
|
|
add_context (win, context, name, description);
|
|
|
|
|
|
|
|
keys = g_key_file_get_keys (kf, context, &len, NULL);
|
|
|
|
for (j = 0; j < len; j++)
|
|
|
|
{
|
|
|
|
const char *key = keys[j];
|
|
|
|
const char *value;
|
|
|
|
|
|
|
|
if (strcmp (key, "Name") == 0 || strcmp (key, "Description") == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
value = g_key_file_get_string (kf, context, key, NULL);
|
|
|
|
|
|
|
|
add_icon (win, key, value, context);
|
|
|
|
}
|
|
|
|
g_strfreev (keys);
|
|
|
|
}
|
|
|
|
g_strfreev (groups);
|
2014-06-24 22:36:29 +00:00
|
|
|
}
|
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
static gboolean
|
|
|
|
filter_by_icon_name (gpointer item,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
return ib_icon_get_name (IB_ICON (item)) != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
symbolic_toggled (IconBrowserWindow *win)
|
|
|
|
{
|
|
|
|
gtk_filter_changed (win->name_filter, GTK_FILTER_CHANGE_DIFFERENT);
|
|
|
|
}
|
|
|
|
|
2017-06-02 19:39:39 +00:00
|
|
|
static void
|
|
|
|
copy_to_clipboard (GtkButton *button,
|
|
|
|
IconBrowserWindow *win)
|
|
|
|
{
|
2017-12-02 14:41:22 +00:00
|
|
|
GdkClipboard *clipboard;
|
2017-06-02 19:39:39 +00:00
|
|
|
|
2017-12-02 14:41:22 +00:00
|
|
|
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (win));
|
|
|
|
gdk_clipboard_set_text (clipboard, gtk_window_get_title (GTK_WINDOW (win->details)));
|
2017-06-02 19:39:39 +00:00
|
|
|
}
|
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
static void
|
2020-07-24 18:40:36 +00:00
|
|
|
set_image (GtkWidget *image, const char *name, int size)
|
2014-07-27 07:32:10 +00:00
|
|
|
{
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
|
|
|
|
gtk_image_set_pixel_size (GTK_IMAGE (image), size);
|
2014-07-27 07:32:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-06-08 18:25:54 +00:00
|
|
|
item_activated (GtkGridView *view,
|
|
|
|
guint position,
|
|
|
|
IconBrowserWindow *win)
|
2014-07-27 07:32:10 +00:00
|
|
|
{
|
2020-08-31 21:06:48 +00:00
|
|
|
GListModel *model = G_LIST_MODEL (gtk_grid_view_get_model (view));
|
2020-06-08 18:25:54 +00:00
|
|
|
IbIcon *icon = g_list_model_get_item (model, position);
|
|
|
|
const char *name;
|
|
|
|
const char *description;
|
|
|
|
gboolean symbolic;
|
2014-07-27 11:44:41 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
name = ib_icon_get_name (icon);
|
|
|
|
description = ib_icon_get_description (icon);
|
|
|
|
symbolic = ib_icon_get_use_symbolic (icon);
|
2014-07-27 11:44:41 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_window_set_title (GTK_WINDOW (win->details), name);
|
|
|
|
set_image (win->image1, name, 8);
|
|
|
|
set_image (win->image2, name, 16);
|
|
|
|
set_image (win->image3, name, 18);
|
|
|
|
set_image (win->image4, name, 24);
|
|
|
|
set_image (win->image5, name, 32);
|
|
|
|
set_image (win->image6, name, 48);
|
|
|
|
set_image (win->image7, name, 64);
|
|
|
|
if (symbolic)
|
|
|
|
{
|
|
|
|
gtk_widget_show (win->image8);
|
|
|
|
gtk_widget_show (win->label8);
|
|
|
|
set_image (win->image8, name, 64);
|
|
|
|
}
|
2014-07-27 11:44:41 +00:00
|
|
|
else
|
2020-06-08 18:25:54 +00:00
|
|
|
{
|
|
|
|
gtk_widget_hide (win->image8);
|
|
|
|
gtk_widget_hide (win->label8);
|
|
|
|
}
|
|
|
|
if (description && description[0])
|
|
|
|
{
|
|
|
|
gtk_label_set_text (GTK_LABEL (win->description), description);
|
|
|
|
gtk_widget_show (win->description);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_hide (win->description);
|
|
|
|
}
|
2017-06-02 01:52:50 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_window_present (GTK_WINDOW (win->details));
|
2014-07-27 07:32:10 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
g_object_unref (icon);
|
2014-11-01 02:28:17 +00:00
|
|
|
}
|
|
|
|
|
2020-01-01 02:06:43 +00:00
|
|
|
static GdkPaintable *
|
|
|
|
get_image_paintable (GtkImage *image)
|
|
|
|
{
|
2020-07-24 18:40:36 +00:00
|
|
|
const char *icon_name;
|
2020-01-01 02:06:43 +00:00
|
|
|
GtkIconTheme *icon_theme;
|
2020-02-04 16:19:22 +00:00
|
|
|
GtkIconPaintable *icon;
|
2020-01-01 02:06:43 +00:00
|
|
|
int size;
|
|
|
|
|
|
|
|
switch (gtk_image_get_storage_type (image))
|
|
|
|
{
|
|
|
|
case GTK_IMAGE_PAINTABLE:
|
|
|
|
return g_object_ref (gtk_image_get_paintable (image));
|
|
|
|
case GTK_IMAGE_ICON_NAME:
|
|
|
|
icon_name = gtk_image_get_icon_name (image);
|
|
|
|
size = gtk_image_get_pixel_size (image);
|
|
|
|
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
|
2020-02-01 23:27:14 +00:00
|
|
|
icon = gtk_icon_theme_lookup_icon (icon_theme,
|
|
|
|
icon_name,
|
2020-02-04 02:53:22 +00:00
|
|
|
NULL,
|
2020-02-01 23:27:14 +00:00
|
|
|
size, 1,
|
|
|
|
gtk_widget_get_direction (GTK_WIDGET (image)),
|
IconTheme: Simplify icon scaling
We had a pretty complex setup where we tried to avoid scaling up themes from dirs
that specified a size. However, not only was it very complex, but it didn't quite
work with window scales, because when using e.g. a size 32 directory for 16@2x
the dir size is wrong anyway. Additionally it turns out most code either picks
an existing icon size, or uses the FORCE_SIZE flags, so it doesn't seem
like a useful behaviour.
This change drops the FORCE_SIZE flags, and always scales
icons. Additionally it moves the scaling of the icon to rendering,
which seems more modern, and allows us to (later) share icons loaded
for different sizes that happened to use the same source file (at
different scales).
Note that this changes the behaviour of
gtk_icon_paintable_download_texture() is it now returns the unscaled
source icon. However, ignore thats, as I plan to remove this function
and replace it with a way to render a paintable to a cairo-surface
instead.
2020-02-05 14:47:23 +00:00
|
|
|
0);
|
2020-01-30 09:52:09 +00:00
|
|
|
if (icon == NULL)
|
2020-06-08 18:25:54 +00:00
|
|
|
{
|
|
|
|
g_print ("no icon for %s\n", icon_name);
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-01-30 09:52:09 +00:00
|
|
|
return GDK_PAINTABLE (icon);
|
2020-03-06 17:53:05 +00:00
|
|
|
case GTK_IMAGE_GICON:
|
|
|
|
case GTK_IMAGE_EMPTY:
|
2020-01-01 02:06:43 +00:00
|
|
|
default:
|
|
|
|
g_warning ("Image storage type %d not handled",
|
|
|
|
gtk_image_get_storage_type (image));
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-22 19:42:26 +00:00
|
|
|
static void
|
2020-01-01 02:06:43 +00:00
|
|
|
drag_begin (GtkDragSource *source,
|
2020-01-06 18:28:25 +00:00
|
|
|
GdkDrag *drag,
|
2020-01-01 02:06:43 +00:00
|
|
|
GtkWidget *widget)
|
2015-02-22 19:42:26 +00:00
|
|
|
{
|
2020-01-01 02:06:43 +00:00
|
|
|
GdkPaintable *paintable;
|
2015-02-22 19:42:26 +00:00
|
|
|
|
2020-01-01 02:06:43 +00:00
|
|
|
paintable = get_image_paintable (GTK_IMAGE (widget));
|
|
|
|
if (paintable)
|
|
|
|
{
|
|
|
|
int w, h;
|
2015-02-22 19:42:26 +00:00
|
|
|
|
2020-01-01 02:06:43 +00:00
|
|
|
w = gdk_paintable_get_intrinsic_width (paintable);
|
|
|
|
h = gdk_paintable_get_intrinsic_height (paintable);
|
|
|
|
gtk_drag_source_set_icon (source, paintable, w, h);
|
|
|
|
g_object_unref (paintable);
|
|
|
|
}
|
|
|
|
}
|
2015-02-22 19:42:26 +00:00
|
|
|
|
2020-02-16 15:22:37 +00:00
|
|
|
static GdkContentProvider *
|
|
|
|
drag_prepare_texture (GtkDragSource *source,
|
|
|
|
double x,
|
|
|
|
double y,
|
|
|
|
GtkWidget *widget)
|
2020-01-01 02:06:43 +00:00
|
|
|
{
|
2020-02-16 15:22:37 +00:00
|
|
|
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
|
2021-02-05 01:46:51 +00:00
|
|
|
GtkSnapshot *snapshot;
|
|
|
|
double width, height;
|
|
|
|
GskRenderNode *node;
|
|
|
|
GskRenderer *renderer;
|
|
|
|
GdkTexture *texture;
|
|
|
|
GdkContentProvider *ret;
|
2020-02-16 15:22:37 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
if (!GDK_IS_PAINTABLE (paintable))
|
2020-02-16 15:22:37 +00:00
|
|
|
return NULL;
|
2020-01-01 02:06:43 +00:00
|
|
|
|
2021-02-05 01:46:51 +00:00
|
|
|
snapshot = gtk_snapshot_new ();
|
|
|
|
width = gdk_paintable_get_intrinsic_width (paintable);
|
|
|
|
height = gdk_paintable_get_intrinsic_height (paintable);
|
|
|
|
gdk_paintable_snapshot (paintable, snapshot, width, height);
|
|
|
|
node = gtk_snapshot_free_to_node (snapshot);
|
|
|
|
|
|
|
|
renderer = gtk_native_get_renderer (gtk_widget_get_native (widget));
|
|
|
|
texture = gsk_renderer_render_texture (renderer, node, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
|
|
|
|
|
|
|
ret = gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture);
|
|
|
|
|
|
|
|
g_object_unref (texture);
|
|
|
|
gsk_render_node_unref (node);
|
|
|
|
|
|
|
|
return ret;
|
2015-02-22 19:42:26 +00:00
|
|
|
}
|
|
|
|
|
2020-02-16 15:22:37 +00:00
|
|
|
static GdkContentProvider *
|
|
|
|
drag_prepare_file (GtkDragSource *source,
|
|
|
|
double x,
|
|
|
|
double y,
|
|
|
|
GtkWidget *widget)
|
2017-08-07 21:33:42 +00:00
|
|
|
{
|
2020-02-16 15:22:37 +00:00
|
|
|
GdkContentProvider *content;
|
2020-02-01 22:38:49 +00:00
|
|
|
GtkIconTheme *icon_theme;
|
2020-01-01 02:06:43 +00:00
|
|
|
const char *name;
|
2020-02-04 16:19:22 +00:00
|
|
|
GtkIconPaintable *info;
|
2017-08-07 21:33:42 +00:00
|
|
|
|
2020-02-16 15:22:37 +00:00
|
|
|
name = gtk_image_get_icon_name (GTK_IMAGE (widget));
|
|
|
|
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
|
2017-08-07 21:33:42 +00:00
|
|
|
|
2020-02-01 23:27:14 +00:00
|
|
|
info = gtk_icon_theme_lookup_icon (icon_theme,
|
|
|
|
name,
|
2020-02-04 02:53:22 +00:00
|
|
|
NULL,
|
2020-02-01 23:27:14 +00:00
|
|
|
32, 1,
|
2020-02-16 15:22:37 +00:00
|
|
|
gtk_widget_get_direction (widget),
|
2020-02-01 23:27:14 +00:00
|
|
|
0);
|
2020-02-16 15:22:37 +00:00
|
|
|
content = gdk_content_provider_new_typed (G_TYPE_FILE, gtk_icon_paintable_get_file (info));
|
2020-01-01 02:06:43 +00:00
|
|
|
g_object_unref (info);
|
2020-02-16 15:22:37 +00:00
|
|
|
|
|
|
|
return content;
|
2017-08-07 21:33:42 +00:00
|
|
|
}
|
|
|
|
|
2015-02-22 19:42:26 +00:00
|
|
|
static void
|
|
|
|
setup_image_dnd (GtkWidget *image)
|
|
|
|
{
|
2020-01-01 02:06:43 +00:00
|
|
|
GtkDragSource *source;
|
|
|
|
|
2020-01-06 19:46:14 +00:00
|
|
|
source = gtk_drag_source_new ();
|
2020-02-16 15:22:37 +00:00
|
|
|
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_texture), image);
|
2020-01-01 02:06:43 +00:00
|
|
|
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
2020-01-07 06:07:02 +00:00
|
|
|
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
2015-02-22 19:42:26 +00:00
|
|
|
}
|
|
|
|
|
2017-08-07 21:33:42 +00:00
|
|
|
static void
|
|
|
|
setup_scalable_image_dnd (GtkWidget *image)
|
|
|
|
{
|
2020-01-01 02:06:43 +00:00
|
|
|
GtkDragSource *source;
|
2017-08-07 21:33:42 +00:00
|
|
|
|
2020-01-06 19:46:14 +00:00
|
|
|
source = gtk_drag_source_new ();
|
2020-02-16 15:22:37 +00:00
|
|
|
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_file), image);
|
2020-01-01 02:06:43 +00:00
|
|
|
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
2020-01-07 06:07:02 +00:00
|
|
|
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
2017-08-07 21:33:42 +00:00
|
|
|
}
|
|
|
|
|
2021-03-04 21:13:46 +00:00
|
|
|
static void
|
|
|
|
search_mode_toggled (GtkSearchBar *searchbar,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
IconBrowserWindow *win)
|
|
|
|
{
|
|
|
|
if (gtk_search_bar_get_search_mode (searchbar))
|
|
|
|
gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (win->context_model), GTK_INVALID_LIST_POSITION);
|
|
|
|
else if (gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (win->context_model)) == GTK_INVALID_LIST_POSITION)
|
|
|
|
gtk_single_selection_set_selected (GTK_SINGLE_SELECTION (win->context_model), 0);
|
|
|
|
|
|
|
|
gtk_filter_changed (win->search_mode_filter, GTK_FILTER_CHANGE_DIFFERENT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
selected_name_changed (GtkSingleSelection *selection,
|
|
|
|
GParamSpec *pspec,
|
|
|
|
IconBrowserWindow *win)
|
|
|
|
{
|
|
|
|
if (gtk_single_selection_get_selected (selection) != GTK_INVALID_LIST_POSITION)
|
|
|
|
gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (win->searchbar), FALSE);
|
|
|
|
}
|
|
|
|
|
2014-06-24 22:36:29 +00:00
|
|
|
static void
|
|
|
|
icon_browser_window_init (IconBrowserWindow *win)
|
|
|
|
{
|
2020-06-08 18:25:54 +00:00
|
|
|
GtkFilter *filter;
|
2015-02-22 17:30:49 +00:00
|
|
|
|
2014-06-24 22:36:29 +00:00
|
|
|
gtk_widget_init_template (GTK_WIDGET (win));
|
|
|
|
|
2015-02-22 19:42:26 +00:00
|
|
|
setup_image_dnd (win->image1);
|
|
|
|
setup_image_dnd (win->image2);
|
|
|
|
setup_image_dnd (win->image3);
|
|
|
|
setup_image_dnd (win->image4);
|
|
|
|
setup_image_dnd (win->image5);
|
IconTheme: Simplify icon scaling
We had a pretty complex setup where we tried to avoid scaling up themes from dirs
that specified a size. However, not only was it very complex, but it didn't quite
work with window scales, because when using e.g. a size 32 directory for 16@2x
the dir size is wrong anyway. Additionally it turns out most code either picks
an existing icon size, or uses the FORCE_SIZE flags, so it doesn't seem
like a useful behaviour.
This change drops the FORCE_SIZE flags, and always scales
icons. Additionally it moves the scaling of the icon to rendering,
which seems more modern, and allows us to (later) share icons loaded
for different sizes that happened to use the same source file (at
different scales).
Note that this changes the behaviour of
gtk_icon_paintable_download_texture() is it now returns the unscaled
source icon. However, ignore thats, as I plan to remove this function
and replace it with a way to render a paintable to a cairo-surface
instead.
2020-02-05 14:47:23 +00:00
|
|
|
setup_image_dnd (win->image6);
|
|
|
|
setup_image_dnd (win->image7);
|
|
|
|
setup_scalable_image_dnd (win->image8);
|
2015-02-22 19:42:26 +00:00
|
|
|
|
2014-07-27 07:32:10 +00:00
|
|
|
gtk_window_set_transient_for (GTK_WINDOW (win->details), GTK_WINDOW (win));
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_search_bar_set_key_capture_widget (GTK_SEARCH_BAR (win->searchbar), GTK_WIDGET (win));
|
2014-07-27 07:32:10 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
populate (win);
|
2014-11-01 02:28:17 +00:00
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
filter = gtk_filter_list_model_get_filter (GTK_FILTER_LIST_MODEL (win->icon_filter_model));
|
2014-07-27 11:44:41 +00:00
|
|
|
|
2020-08-03 19:04:33 +00:00
|
|
|
win->name_filter = GTK_FILTER (gtk_custom_filter_new (filter_by_icon_name, NULL, NULL));
|
2020-06-08 18:25:54 +00:00
|
|
|
|
|
|
|
gtk_multi_filter_append (GTK_MULTI_FILTER (filter), g_object_ref (win->name_filter));
|
2021-03-04 21:13:46 +00:00
|
|
|
|
|
|
|
g_signal_connect (win->searchbar, "notify::search-mode-enabled", G_CALLBACK (search_mode_toggled), win);
|
|
|
|
g_signal_connect (win->context_model, "notify::selected", G_CALLBACK (selected_name_changed), win);
|
2014-06-24 22:36:29 +00:00
|
|
|
}
|
|
|
|
|
2018-02-04 21:21:37 +00:00
|
|
|
static void
|
|
|
|
icon_browser_window_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
IconBrowserWindow *win = ICON_BROWSER_WINDOW (object);
|
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
g_clear_object (&win->name_filter);
|
2018-02-04 21:21:37 +00:00
|
|
|
|
|
|
|
G_OBJECT_CLASS (icon_browser_window_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
2014-06-24 22:36:29 +00:00
|
|
|
static void
|
|
|
|
icon_browser_window_class_init (IconBrowserWindowClass *class)
|
|
|
|
{
|
2018-02-04 21:21:37 +00:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
|
|
|
|
|
object_class->finalize = icon_browser_window_finalize;
|
|
|
|
|
2020-06-08 18:25:54 +00:00
|
|
|
g_type_ensure (IB_TYPE_ICON);
|
|
|
|
g_type_ensure (IB_TYPE_CONTEXT);
|
2015-02-22 17:30:49 +00:00
|
|
|
|
2014-06-24 22:36:29 +00:00
|
|
|
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
|
2016-01-25 01:01:33 +00:00
|
|
|
"/org/gtk/iconbrowser/gtk/window.ui");
|
2014-06-24 22:36:29 +00:00
|
|
|
|
2014-07-27 07:32:10 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, symbolic_radio);
|
2014-06-24 22:36:29 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, searchbar);
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_store);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, icon_filter_model);
|
2021-03-04 21:13:46 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_model);
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, context_store);
|
|
|
|
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, details);
|
2014-06-24 22:36:29 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image1);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image2);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image3);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image4);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image5);
|
2017-08-07 21:33:42 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image6);
|
IconTheme: Simplify icon scaling
We had a pretty complex setup where we tried to avoid scaling up themes from dirs
that specified a size. However, not only was it very complex, but it didn't quite
work with window scales, because when using e.g. a size 32 directory for 16@2x
the dir size is wrong anyway. Additionally it turns out most code either picks
an existing icon size, or uses the FORCE_SIZE flags, so it doesn't seem
like a useful behaviour.
This change drops the FORCE_SIZE flags, and always scales
icons. Additionally it moves the scaling of the icon to rendering,
which seems more modern, and allows us to (later) share icons loaded
for different sizes that happened to use the same source file (at
different scales).
Note that this changes the behaviour of
gtk_icon_paintable_download_texture() is it now returns the unscaled
source icon. However, ignore thats, as I plan to remove this function
and replace it with a way to render a paintable to a cairo-surface
instead.
2020-02-05 14:47:23 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image7);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, image8);
|
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, label8);
|
2014-06-24 22:36:29 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, description);
|
2021-03-04 21:13:46 +00:00
|
|
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), IconBrowserWindow, search_mode_filter);
|
2014-06-24 22:36:29 +00:00
|
|
|
|
2014-07-27 07:32:10 +00:00
|
|
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), item_activated);
|
2017-06-02 19:39:39 +00:00
|
|
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), copy_to_clipboard);
|
2020-06-08 18:25:54 +00:00
|
|
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), symbolic_toggled);
|
2014-06-24 22:36:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
IconBrowserWindow *
|
|
|
|
icon_browser_window_new (IconBrowserApp *app)
|
|
|
|
{
|
|
|
|
return g_object_new (ICON_BROWSER_WINDOW_TYPE, "application", app, NULL);
|
|
|
|
}
|