rofi 1.7.8
icon.c
Go to the documentation of this file.
1/*
2 * rofi
3 *
4 * MIT/X11 License
5 * Copyright © 2013-2018 Qball Cow <qball@gmpclient.org>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
29#define G_LOG_DOMAIN "Widgets.Icon"
30#include "config.h"
31
32#include "theme.h"
33#include "widgets/icon.h"
35#include "widgets/widget.h"
36#include <stdio.h>
37
38#include "rofi-icon-fetcher.h"
39
40struct _icon {
42
43 // Size of the icon.
44 int size;
45
47
48 uint32_t icon_fetch_id;
49
50 double yalign, xalign;
51
52 // Source surface.
53 cairo_surface_t *icon;
54};
55
56static int icon_get_desired_height(widget *wid, G_GNUC_UNUSED const int width) {
57 icon *b = (icon *)wid;
58 int height = b->size;
59 if (b->squared == FALSE) {
60 if (b->icon) {
61 int iconh = cairo_image_surface_get_height(b->icon);
62 int iconw = cairo_image_surface_get_width(b->icon);
63 int icons = MAX(iconh, iconw);
64 double scale = (double)b->size / icons;
65 height = iconh * scale;
66 }
67 }
69 return height;
70}
71static int icon_get_desired_width(widget *wid, G_GNUC_UNUSED const int height) {
72 icon *b = (icon *)wid;
73 int width = b->size;
74 if (b->squared == FALSE) {
75 if (b->icon) {
76 int iconh = cairo_image_surface_get_height(b->icon);
77 int iconw = cairo_image_surface_get_width(b->icon);
78 int icons = MAX(iconh, iconw);
79 double scale = (double)b->size / icons;
80 width = iconw * scale;
81 }
82 }
84 return width;
85}
86
87static void icon_draw(widget *wid, cairo_t *draw) {
88 icon *b = (icon *)wid;
89 // If no icon is loaded. quit.
90 if (b->icon == NULL && b->icon_fetch_id > 0) {
92 if (b->icon) {
93 cairo_surface_reference(b->icon);
94 }
95 }
96 if (b->icon == NULL) {
97 return;
98 }
99 int iconh = cairo_image_surface_get_height(b->icon);
100 int iconw = cairo_image_surface_get_width(b->icon);
101 int icons = MAX(iconh, iconw);
102 double scale = (double)b->size / icons;
103
104 int lpad = widget_padding_get_left(WIDGET(b));
105 int rpad = widget_padding_get_right(WIDGET(b));
106 int tpad = widget_padding_get_top(WIDGET(b));
107 int bpad = widget_padding_get_bottom(WIDGET(b));
108
109 cairo_save(draw);
110
111 cairo_translate(
112 draw, lpad + (b->widget.w - iconw * scale - lpad - rpad) * b->xalign,
113 tpad + (b->widget.h - iconh * scale - tpad - bpad) * b->yalign);
114 cairo_scale(draw, scale, scale);
115 cairo_set_source_surface(draw, b->icon, 0, 0);
116 cairo_paint(draw);
117 cairo_restore(draw);
118}
119
120static void icon_free(widget *wid) {
121 icon *b = (icon *)wid;
122
123 if (b->icon) {
124 cairo_surface_destroy(b->icon);
125 }
126
127 g_free(b);
128}
129
130static void icon_resize(widget *wid, short w, short h) {
131 icon *b = (icon *)wid;
132 if (b->widget.w != w || b->widget.h != h) {
133 b->widget.w = w;
134 b->widget.h = h;
135 widget_update(wid);
136 }
137}
138
139void icon_set_surface(icon *icon_widget, cairo_surface_t *surf) {
140 icon_widget->icon_fetch_id = 0;
141 if (icon_widget->icon) {
142 cairo_surface_destroy(icon_widget->icon);
143 icon_widget->icon = NULL;
144 }
145 if (surf) {
146 cairo_surface_reference(surf);
147 icon_widget->icon = surf;
148 }
149 widget_queue_redraw(WIDGET(icon_widget));
150}
151
152icon *icon_create(widget *parent, const char *name) {
153 icon *b = g_malloc0(sizeof(icon));
154
155 b->size = 16;
156 // Initialize widget.
157 widget_init(WIDGET(b), parent, WIDGET_TYPE_UNKNOWN, name);
158 b->widget.draw = icon_draw;
159 b->widget.free = icon_free;
163
166
167 b->squared = rofi_theme_get_boolean(WIDGET(b), "squared", TRUE);
168
169 const char *filename = rofi_theme_get_string(WIDGET(b), "filename", NULL);
170 if (filename) {
171 b->icon_fetch_id = rofi_icon_fetcher_query(filename, b->size);
172 }
173 b->yalign = rofi_theme_get_double(WIDGET(b), "vertical-align", 0.5);
174 b->yalign = MAX(0, MIN(1.0, b->yalign));
175 b->xalign = rofi_theme_get_double(WIDGET(b), "horizontal-align", 0.5);
176 b->xalign = MAX(0, MIN(1.0, b->xalign));
177
178 return b;
179}
cairo_surface_t * rofi_icon_fetcher_get(const uint32_t uid)
uint32_t rofi_icon_fetcher_query(const char *name, const int size)
void icon_set_surface(icon *icon_widget, cairo_surface_t *surf)
Definition icon.c:139
icon * icon_create(widget *parent, const char *name)
Definition icon.c:152
void widget_queue_redraw(widget *wid)
Definition widget.c:477
void widget_update(widget *wid)
Definition widget.c:467
#define WIDGET(a)
Definition widget.h:119
@ WIDGET_TYPE_UNKNOWN
Definition widget.h:58
static int icon_get_desired_width(widget *wid, G_GNUC_UNUSED const int height)
Definition icon.c:71
static void icon_free(widget *wid)
Definition icon.c:120
static void icon_resize(widget *wid, short w, short h)
Definition icon.c:130
static int icon_get_desired_height(widget *wid, G_GNUC_UNUSED const int width)
Definition icon.c:56
static void icon_draw(widget *wid, cairo_t *draw)
Definition icon.c:87
@ ROFI_ORIENTATION_VERTICAL
Definition rofi-types.h:140
Definition icon.c:40
double xalign
Definition icon.c:50
int squared
Definition icon.c:46
widget widget
Definition icon.c:41
int size
Definition icon.c:44
cairo_surface_t * icon
Definition icon.c:53
uint32_t icon_fetch_id
Definition icon.c:48
double yalign
Definition icon.c:50
void(* free)(struct _widget *widget)
int(* get_desired_width)(struct _widget *, const int height)
int(* get_desired_height)(struct _widget *, const int width)
void(* draw)(struct _widget *widget, cairo_t *draw)
void(* resize)(struct _widget *, short, short)
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition theme.c:1405
double rofi_theme_get_double(const widget *wid, const char *property, double def)
Definition theme.c:1038
int rofi_theme_get_boolean(const widget *wid, const char *property, int def)
Definition theme.c:901
RofiDistance rofi_theme_get_distance(const widget *wid, const char *property, int def)
Definition theme.c:875
const char * rofi_theme_get_string(const widget *wid, const char *property, const char *def)
Definition theme.c:987
void widget_init(widget *wid, widget *parent, WidgetType type, const char *name)
Definition widget.c:35
int widget_padding_get_padding_width(const widget *wid)
Definition widget.c:627
int widget_padding_get_left(const widget *wid)
Definition widget.c:566
int widget_padding_get_right(const widget *wid)
Definition widget.c:576
int widget_padding_get_padding_height(const widget *wid)
Definition widget.c:621
int widget_padding_get_top(const widget *wid)
Definition widget.c:588
int widget_padding_get_bottom(const widget *wid)
Definition widget.c:598