Put images on uiTables. We're going to have to swizzle on OS X after all :(
This commit is contained in:
parent
af0dbd3a0e
commit
cf3182f4d2
63
unix/image.c
63
unix/image.c
|
@ -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;
|
||||
}
|
||||
|
|
24
unix/table.c
24
unix/table.c
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue