1
0
Fork 0
mirror of https://github.com/davatorium/rofi.git synced 2024-10-27 05:23:18 -04:00

[Widget] Add scaling option to background-image.

This commit is contained in:
Dave Davenport 2021-06-15 17:18:34 +02:00
parent f72bae02bb
commit 4c1a74e15e
8 changed files with 120 additions and 11 deletions

View file

@ -366,6 +366,8 @@ dynamic: false;
.IP \(bu 2 .IP \(bu 2
Format: url("path to image"); Format: url("path to image");
.IP \(bu 2 .IP \(bu 2
Format: url("path to image", scale);
.IP \(bu 2
Format: linear\-gradient(stop color,stop1, color, stop2 color, ...); Format: linear\-gradient(stop color,stop1, color, stop2 color, ...);
.IP \(bu 2 .IP \(bu 2
Format: linear\-gradient(to direction, stop color,stop1, color, stop2 color, ...); Format: linear\-gradient(to direction, stop color,stop1, color, stop2 color, ...);
@ -375,7 +377,16 @@ Format: linear\-gradient(angle, stop color,stop1, color, stop2 color, ...);
Angle in deg,rad,grad (as used in color). Angle in deg,rad,grad (as used in color).
.PP .PP
Where the path is a string, and stop color is of type color. Where the \fB\fCpath\fR is a string, and \fB\fCstop\fR color is of type color.
The \fB\fCscale\fR property can be:
.IP \(bu 2
none
.IP \(bu 2
both
.IP \(bu 2
width
.IP \(bu 2
height
.SH Color .SH Color
.PP .PP

View file

@ -255,13 +255,20 @@ dynamic: false;
**rofi** support a very limited set of image formats. **rofi** support a very limited set of image formats.
* Format: url("path to image"); * Format: url("path to image");
* Format: url("path to image", scale);
* Format: linear-gradient(stop color,stop1, color, stop2 color, ...); * Format: linear-gradient(stop color,stop1, color, stop2 color, ...);
* Format: linear-gradient(to direction, stop color,stop1, color, stop2 color, ...); * Format: linear-gradient(to direction, stop color,stop1, color, stop2 color, ...);
where direction is: top,left,right,bottom. where direction is: top,left,right,bottom.
* Format: linear-gradient(angle, stop color,stop1, color, stop2 color, ...); * Format: linear-gradient(angle, stop color,stop1, color, stop2 color, ...);
Angle in deg,rad,grad (as used in color). Angle in deg,rad,grad (as used in color).
Where the path is a string, and stop color is of type color. Where the `path` is a string, and `stop` color is of type color.
The `scale` property can be:
* none
* both
* width
* height
## Color ## Color

View file

@ -35,6 +35,7 @@ void rofi_icon_fetcher_destroy ( void );
* @returns the uid identifying the request. * @returns the uid identifying the request.
*/ */
uint32_t rofi_icon_fetcher_query ( const char *name, const int size ); uint32_t rofi_icon_fetcher_query ( const char *name, const int size );
uint32_t rofi_icon_fetcher_query_advanced ( const char *name, const int wsize, const int hsize );
/** /**
* @param uid The unique id representing the matching request. * @param uid The unique id representing the matching request.

View file

@ -188,11 +188,22 @@ typedef enum
ROFI_DIRECTION_ANGLE, ROFI_DIRECTION_ANGLE,
} RofiDirection; } RofiDirection;
typedef enum
{
ROFI_SCALE_BOTH,
ROFI_SCALE_HEIGHT,
ROFI_SCALE_WIDTH,
ROFI_SCALE_NONE,
} RofiScaleType;
typedef struct typedef struct
{ {
RofiImageType type; RofiImageType type;
char *url; char *url;
RofiScaleType scaling;
int wsize;
int hsize;
RofiDirection dir; RofiDirection dir;
double angle; double angle;

View file

@ -242,6 +242,11 @@ HSL (?i:hsl[a]?)
/* Image type */ /* Image type */
URL (?i:url?) URL (?i:url?)
LINEAR_GRADIENT (?i:linear-gradient?) LINEAR_GRADIENT (?i:linear-gradient?)
WIDTH (?i:width?)
HEIGHT (?i:height?)
BOTH (?i:both?)
TO (?i:to?) TO (?i:to?)
RIGHT (?i:right?) RIGHT (?i:right?)
@ -564,6 +569,9 @@ if ( queue == NULL ){
} }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{URL} { return T_URL; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{URL} { return T_URL; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LINEAR_GRADIENT} { return T_LINEAR_GRADIENT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LINEAR_GRADIENT} { return T_LINEAR_GRADIENT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{WIDTH} { return T_WIDTH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{HEIGHT} { return T_HEIGHT; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{BOTH} { return T_BOTH; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{TO} { return T_TO; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{TO} { return T_TO; }
<PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LEFT} { return T_LEFT; } <PROPERTIES,PROPERTIES_ENV,PROPERTIES_VAR_DEFAULT>{LEFT} { return T_LEFT; }

View file

@ -210,6 +210,9 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%token T_COL_CMYK "cmyk colorscheme" %token T_COL_CMYK "cmyk colorscheme"
%token T_URL "an URL" %token T_URL "an URL"
%token T_WIDTH "an WIDTH"
%token T_HEIGHT "an HEIGHT"
%token T_BOTH "an BOTH"
%token T_TO "an TO" %token T_TO "an TO"
%token T_LEFT "an LEFT" %token T_LEFT "an LEFT"
%token T_RIGHT "an RIGHT" %token T_RIGHT "an RIGHT"
@ -217,6 +220,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
%token T_BOTTOM "an BOTTOM" %token T_BOTTOM "an BOTTOM"
%type <ival> t_property_direction %type <ival> t_property_direction
%type <ival> t_property_scale_type
%token T_LINEAR_GRADIENT "a linear gradient" %token T_LINEAR_GRADIENT "a linear gradient"
%token T_PARENT_LEFT "Parent left ('(')" %token T_PARENT_LEFT "Parent left ('(')"
@ -561,6 +565,12 @@ t_property_element
$$->value.image.type = ROFI_IMAGE_URL; $$->value.image.type = ROFI_IMAGE_URL;
$$->value.image.url = $3; $$->value.image.url = $3;
} }
| T_URL T_PARENT_LEFT T_STRING T_COMMA t_property_scale_type T_PARENT_RIGHT {
$$ = rofi_theme_property_create ( P_IMAGE );
$$->value.image.type = ROFI_IMAGE_URL;
$$->value.image.url = $3;
$$->value.image.scaling = $5;
}
| T_LINEAR_GRADIENT T_PARENT_LEFT t_color_list T_PARENT_RIGHT { | T_LINEAR_GRADIENT T_PARENT_LEFT t_color_list T_PARENT_RIGHT {
$$ = rofi_theme_property_create ( P_IMAGE ); $$ = rofi_theme_property_create ( P_IMAGE );
$$->value.image.type = ROFI_IMAGE_LINEAR_GRADIENT; $$->value.image.type = ROFI_IMAGE_LINEAR_GRADIENT;
@ -589,6 +599,12 @@ t_property_direction
| T_TOP { $$ = ROFI_DIRECTION_TOP; } | T_TOP { $$ = ROFI_DIRECTION_TOP; }
| T_BOTTOM { $$ = ROFI_DIRECTION_BOTTOM; } | T_BOTTOM { $$ = ROFI_DIRECTION_BOTTOM; }
; ;
t_property_scale_type
: T_BOTH { $$ = ROFI_SCALE_BOTH; }
| T_WIDTH { $$ = ROFI_SCALE_WIDTH; }
| T_HEIGHT { $$ = ROFI_SCALE_HEIGHT; }
| T_NONE { $$ = ROFI_SCALE_NONE; }
;
t_color_list t_color_list
: t_property_color { : t_property_color {

View file

@ -77,7 +77,8 @@ typedef struct
unsigned int *acount; unsigned int *acount;
uint32_t uid; uint32_t uid;
int size; int wsize;
int hsize;
cairo_surface_t *surface; cairo_surface_t *surface;
IconFetcherNameEntry *entry; IconFetcherNameEntry *entry;
@ -301,13 +302,13 @@ static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpoint
icon_path = sentry->entry->name; icon_path = sentry->entry->name;
} }
else { else {
icon_path = icon_path_ = nk_xdg_theme_get_icon ( rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name, sentry->size, 1, TRUE ); icon_path = icon_path_ = nk_xdg_theme_get_icon ( rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name, MIN(sentry->wsize,sentry->hsize), 1, TRUE );
if ( icon_path_ == NULL ) { if ( icon_path_ == NULL ) {
g_debug ( "failed to get icon %s(%d): n/a", sentry->entry->name, sentry->size ); g_debug ( "failed to get icon %s(%dx%d): n/a", sentry->entry->name, sentry->wsize, sentry->hsize );
return; return;
} }
else{ else{
g_debug ( "found icon %s(%d): %s", sentry->entry->name, sentry->size, icon_path ); g_debug ( "found icon %s(%dx%d): %s", sentry->entry->name, sentry->wsize, sentry->hsize, icon_path );
} }
} }
cairo_surface_t *icon_surf = NULL; cairo_surface_t *icon_surf = NULL;
@ -318,7 +319,7 @@ static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpoint
} }
GError *error = NULL; GError *error = NULL;
GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale ( icon_path, sentry->size, sentry->size, TRUE, &error ); GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale ( icon_path, sentry->wsize, sentry->hsize, TRUE, &error );
if ( error != NULL ) { if ( error != NULL ) {
g_warning ( "Failed to load image: %s", error->message ); g_warning ( "Failed to load image: %s", error->message );
g_error_free ( error ); g_error_free ( error );
@ -336,6 +337,40 @@ static void rofi_icon_fetcher_worker ( thread_state *sdata, G_GNUC_UNUSED gpoint
rofi_view_reload (); rofi_view_reload ();
} }
uint32_t rofi_icon_fetcher_query_advanced ( const char *name, const int wsize, const int hsize )
{
g_debug ( "Query: %s(%dx%d)", name, wsize, hsize );
IconFetcherNameEntry *entry = g_hash_table_lookup ( rofi_icon_fetcher_data->icon_cache, name );
if ( entry == NULL ) {
entry = g_new0 ( IconFetcherNameEntry, 1 );
entry->name = g_strdup ( name );
g_hash_table_insert ( rofi_icon_fetcher_data->icon_cache, entry->name, entry );
}
IconFetcherEntry *sentry;
for ( GList *iter = g_list_first ( entry->sizes ); iter; iter = g_list_next ( iter ) ) {
sentry = iter->data;
if ( sentry->wsize == wsize && sentry->hsize == hsize ) {
return sentry->uid;
}
}
// Not found.
sentry = g_new0 ( IconFetcherEntry, 1 );
sentry->uid = ++( rofi_icon_fetcher_data->last_uid );
sentry->wsize = wsize;
sentry->hsize = hsize;
sentry->entry = entry;
sentry->surface = NULL;
entry->sizes = g_list_prepend ( entry->sizes, sentry );
g_hash_table_insert ( rofi_icon_fetcher_data->icon_cache_uid, GINT_TO_POINTER ( sentry->uid ), sentry );
// Push into fetching queue.
sentry->state.callback = rofi_icon_fetcher_worker;
g_thread_pool_push ( tpool, sentry, NULL );
return sentry->uid;
}
uint32_t rofi_icon_fetcher_query ( const char *name, const int size ) uint32_t rofi_icon_fetcher_query ( const char *name, const int size )
{ {
g_debug ( "Query: %s(%d)", name, size ); g_debug ( "Query: %s(%d)", name, size );
@ -348,7 +383,7 @@ uint32_t rofi_icon_fetcher_query ( const char *name, const int size )
IconFetcherEntry *sentry; IconFetcherEntry *sentry;
for ( GList *iter = g_list_first ( entry->sizes ); iter; iter = g_list_next ( iter ) ) { for ( GList *iter = g_list_first ( entry->sizes ); iter; iter = g_list_next ( iter ) ) {
sentry = iter->data; sentry = iter->data;
if ( sentry->size == size ) { if ( sentry->wsize == size && sentry->hsize == size ) {
return sentry->uid; return sentry->uid;
} }
} }
@ -356,7 +391,8 @@ uint32_t rofi_icon_fetcher_query ( const char *name, const int size )
// Not found. // Not found.
sentry = g_new0 ( IconFetcherEntry, 1 ); sentry = g_new0 ( IconFetcherEntry, 1 );
sentry->uid = ++( rofi_icon_fetcher_data->last_uid ); sentry->uid = ++( rofi_icon_fetcher_data->last_uid );
sentry->size = size; sentry->wsize = size;
sentry->hsize = size;
sentry->entry = entry; sentry->entry = entry;
sentry->surface = NULL; sentry->surface = NULL;

View file

@ -996,8 +996,27 @@ gboolean rofi_theme_get_image ( const widget *widget, const char *property, cair
return FALSE; return FALSE;
} }
if ( p->value.image.type == ROFI_IMAGE_URL ) { if ( p->value.image.type == ROFI_IMAGE_URL ) {
if ( p->value.image.surface_id == 0 ) { int wsize = -1;
p->value.image.surface_id = rofi_icon_fetcher_query ( p->value.image.url, -1 ); int hsize = -1;
switch ( p->value.image.scaling ) {
case ROFI_SCALE_BOTH:
wsize = widget->w;
hsize = widget->h;
break;
case ROFI_SCALE_WIDTH:
wsize = widget->w;
break;
case ROFI_SCALE_HEIGHT:
hsize = widget->h;
break;
case ROFI_SCALE_NONE:
default:
break;
}
if ( p->value.image.surface_id == 0 || p->value.image.wsize != wsize || p->value.image.hsize != hsize) {
p->value.image.surface_id = rofi_icon_fetcher_query_advanced ( p->value.image.url, wsize, hsize );
p->value.image.wsize = wsize;
p->value.image.hsize = hsize;
} }
cairo_surface_t *img = rofi_icon_fetcher_get ( p->value.image.surface_id ); cairo_surface_t *img = rofi_icon_fetcher_get ( p->value.image.surface_id );