mirror of
https://github.com/davatorium/rofi.git
synced 2024-11-18 13:54:36 -05:00
[Theme] Support multiple stops in linear-gradient
* Fix anchor dumping * Fix image dumping
This commit is contained in:
parent
beccfe4178
commit
7cf0385681
5 changed files with 121 additions and 37 deletions
|
@ -392,12 +392,12 @@ 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: linear\-gradient(start color,stop color);
|
Format: linear\-gradient(stop color,stop1, color, stop2 color, ...);
|
||||||
|
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
Where the path is a string, and start/stop color is of type color.
|
Where the path is a string, and stop color is of type color.
|
||||||
|
|
||||||
.SH Color
|
.SH Color
|
||||||
.PP
|
.PP
|
||||||
|
|
|
@ -255,9 +255,9 @@ 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: linear-gradient(start color,stop color);
|
* Format: linear-gradient(stop color,stop1, color, stop2 color, ...);
|
||||||
|
|
||||||
Where the path is a string, and start/stop color is of type color.
|
Where the path is a string, and stop color is of type color.
|
||||||
|
|
||||||
## Color
|
## Color
|
||||||
|
|
||||||
|
|
|
@ -182,10 +182,8 @@ typedef struct
|
||||||
{
|
{
|
||||||
RofiImageType type;
|
RofiImageType type;
|
||||||
char *url;
|
char *url;
|
||||||
/** Start color */
|
/** colors */
|
||||||
ThemeColor start;
|
GList *colors;
|
||||||
/** Stop color */
|
|
||||||
ThemeColor stop;
|
|
||||||
|
|
||||||
/** cached image */
|
/** cached image */
|
||||||
uint32_t surface_id;
|
uint32_t surface_id;
|
||||||
|
|
|
@ -257,6 +257,7 @@ static ThemeColor hwb_to_rgb ( double h, double w, double b)
|
||||||
%type <theme> t_entry_list
|
%type <theme> t_entry_list
|
||||||
%type <list> t_entry_name_path
|
%type <list> t_entry_name_path
|
||||||
%type <list> t_entry_name_path_selectors
|
%type <list> t_entry_name_path_selectors
|
||||||
|
%type <list> t_color_list
|
||||||
%type <property> t_property
|
%type <property> t_property
|
||||||
%type <property> t_property_element
|
%type <property> t_property_element
|
||||||
%type <property_list> t_property_list
|
%type <property_list> t_property_list
|
||||||
|
@ -536,14 +537,25 @@ t_property_element
|
||||||
$$->value.image.type = ROFI_IMAGE_URL;
|
$$->value.image.type = ROFI_IMAGE_URL;
|
||||||
$$->value.image.url = $3;
|
$$->value.image.url = $3;
|
||||||
}
|
}
|
||||||
| T_LINEAR_GRADIENT T_PARENT_LEFT t_property_color T_COMMA t_property_color 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;
|
||||||
$$->value.image.start = $3;
|
$$->value.image.colors = $3;
|
||||||
$$->value.image.stop = $5;
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
t_color_list
|
||||||
|
: t_property_color {
|
||||||
|
$$ = g_list_append ( NULL, g_memdup ( (gconstpointer)&($1), sizeof ( ThemeColor )));
|
||||||
|
}
|
||||||
|
| t_color_list T_COMMA t_property_color {
|
||||||
|
|
||||||
|
$$ = g_list_append ($1, g_memdup ( (gconstpointer)&($3), sizeof ( ThemeColor )));
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** List of elements */
|
/** List of elements */
|
||||||
t_property_element_list_optional
|
t_property_element_list_optional
|
||||||
: %empty { $$ = NULL; }
|
: %empty { $$ = NULL; }
|
||||||
|
|
126
source/theme.c
126
source/theme.c
|
@ -33,6 +33,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
// GFile stuff.
|
// GFile stuff.
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
@ -140,6 +141,12 @@ Property* rofi_theme_property_copy ( const Property *p )
|
||||||
{
|
{
|
||||||
retv->value = p->value;
|
retv->value = p->value;
|
||||||
retv->value.image.url = g_strdup ( p->value.image.url );
|
retv->value.image.url = g_strdup ( p->value.image.url );
|
||||||
|
retv->value.image.colors = NULL;
|
||||||
|
for ( GList *l = g_list_first ( p->value.image.colors );
|
||||||
|
l ; l = g_list_next(l)){
|
||||||
|
retv->value.image.colors = g_list_append ( retv->value.image.colors,
|
||||||
|
g_memdup ( l->data, sizeof(ThemeColor)));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -197,6 +204,9 @@ void rofi_theme_property_free ( Property *p )
|
||||||
if ( p->value.image.url ) {
|
if ( p->value.image.url ) {
|
||||||
g_free( p->value.image.url );
|
g_free( p->value.image.url );
|
||||||
}
|
}
|
||||||
|
if ( p->value.image.colors ) {
|
||||||
|
g_list_free_full ( p->value.image.colors, g_free );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_slice_free ( Property, p );
|
g_slice_free ( Property, p );
|
||||||
}
|
}
|
||||||
|
@ -358,19 +368,6 @@ static void rofi_theme_print_distance ( RofiDistance d )
|
||||||
printf ( "dash " );
|
printf ( "dash " );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Textual representation of Window Location */
|
|
||||||
const char * const WindowLocationStr[9] = {
|
|
||||||
"center",
|
|
||||||
"northwest",
|
|
||||||
"north",
|
|
||||||
"northeast",
|
|
||||||
"east",
|
|
||||||
"southeast",
|
|
||||||
"south",
|
|
||||||
"southwest",
|
|
||||||
"west"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Textual representation of RofiCursorType */
|
/** Textual representation of RofiCursorType */
|
||||||
const char *const RofiCursorTypeStr[3] = {
|
const char *const RofiCursorTypeStr[3] = {
|
||||||
"default",
|
"default",
|
||||||
|
@ -420,8 +417,39 @@ static void int_rofi_theme_print_property ( Property *p )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case P_POSITION:
|
case P_POSITION:
|
||||||
printf ( "%s", WindowLocationStr[p->value.i] );
|
{
|
||||||
break;
|
switch ( p->value.i)
|
||||||
|
{
|
||||||
|
case WL_CENTER:
|
||||||
|
fputs("center",stdout);
|
||||||
|
break;
|
||||||
|
case WL_NORTH:
|
||||||
|
fputs("north",stdout);
|
||||||
|
break;
|
||||||
|
case WL_SOUTH:
|
||||||
|
fputs("south",stdout);
|
||||||
|
break;
|
||||||
|
case WL_WEST:
|
||||||
|
fputs("west",stdout);
|
||||||
|
break;
|
||||||
|
case WL_EAST:
|
||||||
|
fputs("east",stdout);
|
||||||
|
break;
|
||||||
|
case WL_NORTH|WL_EAST:
|
||||||
|
fputs("northeast",stdout);
|
||||||
|
break;
|
||||||
|
case WL_SOUTH|WL_EAST:
|
||||||
|
fputs("southeast",stdout);
|
||||||
|
break;
|
||||||
|
case WL_NORTH|WL_WEST:
|
||||||
|
fputs("northwest",stdout);
|
||||||
|
break;
|
||||||
|
case WL_SOUTH|WL_WEST:
|
||||||
|
fputs("southwest",stdout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case P_STRING:
|
case P_STRING:
|
||||||
printf ( "\"%s\"", p->value.s );
|
printf ( "\"%s\"", p->value.s );
|
||||||
break;
|
break;
|
||||||
|
@ -429,8 +457,13 @@ static void int_rofi_theme_print_property ( Property *p )
|
||||||
printf ( "%d", p->value.i );
|
printf ( "%d", p->value.i );
|
||||||
break;
|
break;
|
||||||
case P_DOUBLE:
|
case P_DOUBLE:
|
||||||
printf ( "%.2f", p->value.f );
|
{
|
||||||
break;
|
char sign = (p->value.f < 0);
|
||||||
|
int top = (int)fabs(p->value.f);
|
||||||
|
int bottom = (fabs(fmod(p->value.f,1.0)))*100;
|
||||||
|
printf ( "%s%d.%02d",sign?"-":"", top,bottom);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case P_BOOLEAN:
|
case P_BOOLEAN:
|
||||||
printf ( "%s", p->value.b ? "true" : "false" );
|
printf ( "%s", p->value.b ? "true" : "false" );
|
||||||
break;
|
break;
|
||||||
|
@ -441,6 +474,31 @@ static void int_rofi_theme_print_property ( Property *p )
|
||||||
( p->value.color.blue * 255.0 ),
|
( p->value.color.blue * 255.0 ),
|
||||||
( p->value.color.alpha * 100.0 ) );
|
( p->value.color.alpha * 100.0 ) );
|
||||||
break;
|
break;
|
||||||
|
case P_IMAGE:
|
||||||
|
{
|
||||||
|
if ( p->value.image.type == ROFI_IMAGE_URL ) {
|
||||||
|
printf("url (\"%s\")", p->value.s );
|
||||||
|
} else if ( p->value.image.type == ROFI_IMAGE_LINEAR_GRADIENT ) {
|
||||||
|
printf("linear-gradient ( ");
|
||||||
|
guint length = g_list_length ( p->value.image.colors);
|
||||||
|
guint index = 0;
|
||||||
|
for ( GList *l = g_list_first ( p->value.image.colors); l != NULL; l = g_list_next(l)) {
|
||||||
|
ThemeColor *color = (ThemeColor*)l->data;
|
||||||
|
printf ( "rgba ( %.0f, %.0f, %.0f, %.0f %% )",
|
||||||
|
( color->red * 255.0 ),
|
||||||
|
( color->green * 255.0 ),
|
||||||
|
( color->blue * 255.0 ),
|
||||||
|
( color->alpha * 100.0 ) );
|
||||||
|
index++;
|
||||||
|
if ( index < length ) {
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case P_PADDING:
|
case P_PADDING:
|
||||||
if ( distance_compare ( p->value.padding.top, p->value.padding.bottom ) &&
|
if ( distance_compare ( p->value.padding.top, p->value.padding.bottom ) &&
|
||||||
distance_compare ( p->value.padding.left, p->value.padding.right ) &&
|
distance_compare ( p->value.padding.left, p->value.padding.right ) &&
|
||||||
|
@ -944,15 +1002,31 @@ gboolean rofi_theme_get_image ( const widget *widget, const char *property, cair
|
||||||
}
|
}
|
||||||
} else if ( p->value.image.type == ROFI_IMAGE_LINEAR_GRADIENT ) {
|
} else if ( p->value.image.type == ROFI_IMAGE_LINEAR_GRADIENT ) {
|
||||||
cairo_pattern_t * pat = cairo_pattern_create_linear (0.0,0.0, widget->w, 0.0);
|
cairo_pattern_t * pat = cairo_pattern_create_linear (0.0,0.0, widget->w, 0.0);
|
||||||
cairo_pattern_add_color_stop_rgba ( pat, 0.0,
|
guint length = g_list_length ( p->value.image.colors );
|
||||||
p->value.image.start.red, p->value.image.start.green,
|
if ( length > 1 ){
|
||||||
p->value.image.start.blue, p->value.image.start.alpha);
|
length--;
|
||||||
cairo_pattern_add_color_stop_rgba ( pat, 1.0,
|
guint color_index = 0;
|
||||||
p->value.image.stop.red, p->value.image.stop.green,
|
for ( GList *l = g_list_first ( p->value.image.colors); l != NULL ; l = g_list_next ( l ) )
|
||||||
p->value.image.stop.blue, p->value.image.stop.alpha);
|
{
|
||||||
cairo_set_source ( d, pat );
|
ThemeColor *c = (ThemeColor*) (l->data);
|
||||||
cairo_pattern_destroy ( pat );
|
cairo_pattern_add_color_stop_rgba ( pat,(color_index)/(double)length,
|
||||||
return TRUE;
|
c->red, c->green,
|
||||||
|
c->blue, c->alpha);
|
||||||
|
color_index++;
|
||||||
|
}
|
||||||
|
cairo_set_source ( d, pat );
|
||||||
|
cairo_pattern_destroy ( pat );
|
||||||
|
return TRUE;
|
||||||
|
} else if ( length == 1 ) {
|
||||||
|
ThemeColor *c = (ThemeColor*) (p->value.image.colors->data);
|
||||||
|
cairo_pattern_add_color_stop_rgba ( pat,0,
|
||||||
|
c->red, c->green,
|
||||||
|
c->blue, c->alpha);
|
||||||
|
cairo_set_source ( d, pat );
|
||||||
|
cairo_pattern_destroy ( pat );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue