diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/dialogs/combi.c | 13 | ||||
-rw-r--r-- | source/mode.c | 12 | ||||
-rw-r--r-- | source/view.c | 8 | ||||
-rw-r--r-- | source/widgets/textbox.c | 39 | ||||
-rw-r--r-- | source/x11-helper.c | 24 |
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 ) |