Put images on uiTables. We're going to have to swizzle on OS X after all :(

This commit is contained in:
Pietro Gagliardi 2016-06-27 16:11:15 -04:00
parent af0dbd3a0e
commit cf3182f4d2
3 changed files with 89 additions and 2 deletions

View File

@ -45,7 +45,7 @@ void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, in
cstride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixelWidth);
buf = (unsigned char *) uiAlloc((cstride * pixelHeight * 4) * sizeof (unsigned char), "unsigned char[]");
p = buf;
for (y = 0; y < pixelWidth * pixelHeight; y += pixelStride) {
for (y = 0; y < pixelStride * pixelHeight; y += pixelStride) {
memmove(p, src + y, cstride);
p += cstride;
}
@ -57,3 +57,64 @@ void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, in
cairo_surface_flush(cs);
g_ptr_array_add(i->images, cs);
}
struct matcher {
cairo_surface_t *best;
int distX;
int distY;
int targetX;
int targetY;
gboolean foundLarger;
};
// TODO is this the right algorithm?
static void match(gpointer surface, gpointer data)
{
cairo_surface_t *cs = (cairo_surface_t *) surface;
struct matcher *m = (struct matcher *) data;
int x, y;
int x2, y2;
x = cairo_image_surface_get_width(cs);
y = cairo_image_surface_get_height(cs);
if (m->best == NULL)
goto writeMatch;
if (x < m->targetX && y < m->targetY)
if (m->foundLarger)
// always prefer larger ones
return;
if (x >= m->targetX && y >= m->targetY && !m->foundLarger)
// we set foundLarger below
goto writeMatch;
x2 = abs(m->targetX - x);
y2 = abs(m->targetY - y);
if (x2 < m->distX && y2 < m->distY)
goto writeMatch;
// TODO weight one dimension? threshhold?
return;
writeMatch:
// must set this here too; otherwise the first image will never have ths set
if (x >= m->targetX && y >= m->targetY && !m->foundLarger)
m->foundLarger = TRUE;
m->best = cs;
m->distX = abs(m->targetX - x);
m->distY = abs(m->targetY - y);
}
cairo_surface_t *imageAppropriateSurface(uiImage *i, GtkWidget *w)
{
struct matcher m;
m.best = NULL;
m.distX = G_MAXINT;
m.distY = G_MAXINT;
m.targetX = i->width * gtk_widget_get_scale_factor(w);
m.targetY = i->height * gtk_widget_get_scale_factor(w);
m.foundLarger = FALSE;
g_ptr_array_foreach(i->images, match, &m);
return m.best;
}

View File

@ -334,6 +334,25 @@ struct uiTable {
int backgroundColumn;
};
// use the same size as GtkFileChooserWidget's treeview
// TODO refresh when icon theme changes
// TODO doesn't work when scaled
// TODO is this even necessary?
static void setImageSize(GtkCellRenderer *r)
{
gint size;
gint width, height;
gint xpad, ypad;
size = 16; // fallback used by GtkFileChooserWidget
if (gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height) != FALSE)
size = MAX(width, height);
gtk_cell_renderer_get_padding(r, &xpad, &ypad);
gtk_cell_renderer_set_fixed_size(r,
2 * xpad + size,
2 * ypad + size);
}
static void dataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *mm, GtkTreeIter *iter, gpointer data)
{
struct tablePart *part = (struct tablePart *) data;
@ -352,9 +371,12 @@ static void dataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *mm,
g_object_set(r, "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
break;
case partImage:
//TODO setImageSize(r);
gtk_tree_model_get_value(mm, iter, part->imageColumn, &value);
img = (uiImage *) g_value_get_pointer(&value);
// TODO
g_object_set(r, "surface",
imageAppropriateSurface(img, part->tv->treeWidget),
NULL);
g_object_set(r, "mode", GTK_CELL_RENDERER_MODE_INERT, NULL);
break;
case partButton:

View File

@ -8,6 +8,7 @@
#include <dlfcn.h> // see drawtext.c
#include <langinfo.h>
#include <string.h>
#include <stdlib.h>
#include "../ui.h"
#include "../ui_unix.h"
#include "../common/uipriv.h"
@ -50,3 +51,6 @@ extern PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc);
// graphemes.c
extern ptrdiff_t *graphemes(const char *text, PangoContext *context);
// image.c
extern cairo_surface_t *imageAppropriateSurface(uiImage *i, GtkWidget *w);