summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorAaron Ash <aaron.ash@gmail.com>2017-04-12 17:58:32 +0200
committerQuentin Glidic <sardemff7+git@sardemff7.net>2017-05-30 19:00:57 +0200
commit43053cdfc34539dd73ba6a028090038f99d4093e (patch)
tree787829616f0e34cd92a89ee65d712db668e4b67a /source
parent4e6af2eab84157794684c485d15fb9624ec0f306 (diff)
view: Add icon (basic) support
Diffstat (limited to 'source')
-rw-r--r--source/dialogs/combi.c13
-rw-r--r--source/mode.c12
-rw-r--r--source/view.c8
-rw-r--r--source/widgets/textbox.c39
-rw-r--r--source/x11-helper.c24
5 files changed, 92 insertions, 4 deletions
diff --git a/source/dialogs/combi.c b/source/dialogs/combi.c
index 8fa4a438..5631c519 100644
--- a/source/dialogs/combi.c
+++ b/source/dialogs/combi.c
@@ -247,6 +247,18 @@ static char * combi_get_completion ( const Mode *sw, unsigned int index )
return NULL;
}
+static cairo_surface_t * combi_get_icon ( const Mode *sw, unsigned int index, int height )
+{
+ CombiModePrivateData *pd = mode_get_private_data ( sw );
+ for ( unsigned i = 0; i < pd->num_switchers; i++ ) {
+ if ( index >= pd->starts[i] && index < ( pd->starts[i] + pd->lengths[i] ) ) {
+ cairo_surface_t *icon = mode_get_icon ( pd->switchers[i].mode, index - pd->starts[i], height );
+ return icon;
+ }
+ }
+ return NULL;
+}
+
static char * combi_preprocess_input ( Mode *sw, const char *input )
{
CombiModePrivateData *pd = mode_get_private_data ( sw );
@@ -285,6 +297,7 @@ Mode combi_mode =
._token_match = combi_mode_match,
._get_completion = combi_get_completion,
._get_display_value = combi_mgrv,
+ ._get_icon = combi_get_icon,
._preprocess_input = combi_preprocess_input,
.private_data = NULL,
.free = NULL
diff --git a/source/mode.c b/source/mode.c
index a7e552d3..5e070e3c 100644
--- a/source/mode.c
+++ b/source/mode.c
@@ -70,6 +70,18 @@ char * mode_get_display_value ( const Mode *mode, unsigned int selected_line, in
return mode->_get_display_value ( mode, selected_line, state, attribute_list, get_entry );
}
+cairo_surface_t * mode_get_icon ( const Mode *mode, unsigned int selected_line, int height )
+{
+ g_assert ( mode != NULL );
+
+ if ( mode->_get_icon != NULL ) {
+ return mode->_get_icon ( mode, selected_line, height );
+ }
+ else {
+ return NULL;
+ }
+}
+
char * mode_get_completion ( const Mode *mode, unsigned int selected_line )
{
g_assert ( mode != NULL );
diff --git a/source/view.c b/source/view.c
index e33e89ed..4745990c 100644
--- a/source/view.c
+++ b/source/view.c
@@ -906,6 +906,14 @@ static void update_callback ( textbox *t, unsigned int index, void *udata, TextB
else{
list = pango_attr_list_new ();
}
+ int icon_height = textbox_get_font_height ( t );
+
+ cairo_surface_t *icon = mode_get_icon ( state->sw, state->line_map[index], icon_height );
+ textbox_icon ( t, icon );
+
+ //AA TODO: Find a better way to position icon than tab char
+ gchar *firstspace = g_utf8_strchr ( t->text, -1, '\t' );
+ textbox_set_icon_index ( t, ( firstspace == NULL ) ? -1 : g_utf8_pointer_to_offset ( t->text, firstspace ) + 1 );
if ( state->tokens && config.show_match ) {
ThemeHighlight th = { HL_BOLD | HL_UNDERLINE, { 0.0, 0.0, 0.0, 0.0 } };
diff --git a/source/widgets/textbox.c b/source/widgets/textbox.c
index 9fd9c0f5..ee51367a 100644
--- a/source/widgets/textbox.c
+++ b/source/widgets/textbox.c
@@ -186,6 +186,8 @@ textbox* textbox_create_full ( WidgetType type, const char *name, TextboxFlags f
tb->widget.trigger_action = textbox_editable_trigger_action;
}
+ tb->icon_index = -1; //Don't draw the icon by default
+
// Enabled by default
tb->widget.enabled = rofi_theme_get_boolean ( WIDGET ( tb ), "enabled", TRUE );
return tb;
@@ -267,6 +269,12 @@ void textbox_set_pango_attributes ( textbox *tb, PangoAttrList *list )
pango_layout_set_attributes ( tb->layout, list );
}
+void textbox_set_icon_index ( textbox *tb, int index )
+{
+ tb->icon_index = index;
+ widget_queue_redraw ( WIDGET ( tb ) );
+}
+
// set the default text to display
void textbox_text ( textbox *tb, const char *text )
{
@@ -297,6 +305,13 @@ void textbox_text ( textbox *tb, const char *text )
widget_queue_redraw ( WIDGET ( tb ) );
}
+void textbox_icon ( textbox *tb, cairo_surface_t *icon )
+{
+ tb->icon = icon;
+
+ widget_queue_redraw ( WIDGET ( tb ) );
+}
+
// within the parent handled auto width/height modes
void textbox_moveresize ( textbox *tb, int x, int y, int w, int h )
{
@@ -363,7 +378,26 @@ static void textbox_draw ( widget *wid, cairo_t *draw )
}
// Skip the side MARGIN on the X axis.
- int x = widget_padding_get_left ( WIDGET ( tb ) ) + offset;
+ int x = widget_padding_get_left ( WIDGET ( tb ) ) + offset;
+ int top = widget_padding_get_top ( WIDGET ( tb ) );
+ int y = top + ( pango_font_metrics_get_ascent ( tb->metrics ) - pango_layout_get_baseline ( tb->layout ) ) / PANGO_SCALE;
+
+ // draw Icon
+ int iconheight = textbox_get_font_height ( tb );
+ int translatex = ( textbox_get_estimated_char_height () * tb->icon_index / 2 );
+ if ( tb->icon != NULL && tb->icon_index != -1 ) {
+ cairo_save ( draw );
+
+ /*int iconw = cairo_image_surface_get_width (tb->icon);*/
+ int iconh = cairo_image_surface_get_height ( tb->icon );
+ double scale = (double) iconheight / iconh;
+
+ cairo_translate ( draw, translatex, 0 );
+ cairo_scale ( draw, scale, scale );
+ cairo_set_source_surface ( draw, tb->icon, x, y );
+ cairo_paint ( draw );
+ cairo_restore ( draw );
+ }
if ( tb->flags & TB_RIGHT ) {
int line_width = 0;
@@ -376,14 +410,11 @@ static void textbox_draw ( widget *wid, cairo_t *draw )
x = ( ( tb->widget.w - tw - widget_padding_get_padding_width ( WIDGET ( tb ) ) - offset ) ) / 2;
}
- int top = widget_padding_get_top ( WIDGET ( tb ) );
-
rofi_theme_get_color ( WIDGET ( tb ), "foreground", draw );
// Text
rofi_theme_get_color ( WIDGET ( tb ), "text", draw );
// draw the cursor
if ( tb->flags & TB_EDITABLE && tb->blink ) {
- int y = top + ( pango_font_metrics_get_ascent ( tb->metrics ) - pango_layout_get_baseline ( tb->layout ) ) / PANGO_SCALE;
// We want to place the cursor based on the text shown.
const char *text = pango_layout_get_text ( tb->layout );
// Clamp the position, should not be needed, but we are paranoid.
diff --git a/source/x11-helper.c b/source/x11-helper.c
index 689d0519..94b5b53d 100644
--- a/source/x11-helper.c
+++ b/source/x11-helper.c
@@ -133,6 +133,30 @@ cairo_surface_t * x11_helper_get_bg_surface ( void )
xcb->screen->width_in_pixels, xcb->screen->height_in_pixels );
}
+cairo_surface_t* cairo_image_surface_create_from_svg ( const gchar* file, int height )
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ RsvgHandle * handle;
+ RsvgDimensionData dimensions;
+
+ handle = rsvg_handle_new_from_file ( file, NULL );
+ rsvg_handle_get_dimensions ( handle, &dimensions );
+ double scale = (double) height / dimensions.height;
+ surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32,
+ (double) dimensions.width * scale,
+ (double) dimensions.height * scale );
+ cr = cairo_create ( surface );
+ cairo_scale ( cr, scale, scale );
+ rsvg_handle_render_cairo ( handle, cr );
+ cairo_destroy ( cr );
+
+ rsvg_handle_close ( handle, NULL );
+ g_object_unref ( handle );
+
+ return surface;
+}
+
// retrieve a text property from a window
// technically we could use window_get_prop(), but this is better for character set support
char* window_get_text_prop ( xcb_window_t w, xcb_atom_t atom )