rofi  1.7.5
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 
31 #include "widgets/icon.h"
32 #include "theme.h"
34 #include "widgets/widget.h"
35 #include <stdio.h>
36 
37 #include "rofi-icon-fetcher.h"
38 
39 struct _icon {
41 
42  // Size of the icon.
43  int size;
44 
45  int squared;
46 
47  uint32_t icon_fetch_id;
48 
49  double yalign, xalign;
50 
51  // Source surface.
52  cairo_surface_t *icon;
53 };
54 
56  G_GNUC_UNUSED const int width) {
57  icon *b = (icon *)widget;
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 }
72  G_GNUC_UNUSED const int height) {
73  icon *b = (icon *)widget;
74  int width = b->size;
75  if (b->squared == FALSE) {
76  if (b->icon) {
77  int iconh = cairo_image_surface_get_height(b->icon);
78  int iconw = cairo_image_surface_get_width(b->icon);
79  int icons = MAX(iconh, iconw);
80  double scale = (double)b->size / icons;
81  width = iconw * scale;
82  }
83  }
85  return width;
86 }
87 
88 static void icon_draw(widget *wid, cairo_t *draw) {
89  icon *b = (icon *)wid;
90  // If no icon is loaded. quit.
91  if (b->icon == NULL && b->icon_fetch_id > 0) {
93  if (b->icon) {
94  cairo_surface_reference(b->icon);
95  }
96  }
97  if (b->icon == NULL) {
98  return;
99  }
100  int iconh = cairo_image_surface_get_height(b->icon);
101  int iconw = cairo_image_surface_get_width(b->icon);
102  int icons = MAX(iconh, iconw);
103  double scale = (double)b->size / icons;
104 
105  int lpad = widget_padding_get_left(WIDGET(b));
106  int rpad = widget_padding_get_right(WIDGET(b));
107  int tpad = widget_padding_get_top(WIDGET(b));
108  int bpad = widget_padding_get_bottom(WIDGET(b));
109 
110  cairo_save(draw);
111 
112  cairo_translate(
113  draw, lpad + (b->widget.w - iconw * scale - lpad - rpad) * b->xalign,
114  tpad + (b->widget.h - iconh * scale - tpad - bpad) * b->yalign);
115  cairo_scale(draw, scale, scale);
116  cairo_set_source_surface(draw, b->icon, 0, 0);
117  cairo_paint(draw);
118  cairo_restore(draw);
119 }
120 
121 static void icon_free(widget *wid) {
122  icon *b = (icon *)wid;
123 
124  if (b->icon) {
125  cairo_surface_destroy(b->icon);
126  }
127 
128  g_free(b);
129 }
130 
131 static void icon_resize(widget *widget, short w, short h) {
132  icon *b = (icon *)widget;
133  if (b->widget.w != w || b->widget.h != h) {
134  b->widget.w = w;
135  b->widget.h = h;
137  }
138 }
139 
140 void icon_set_surface(icon *icon, cairo_surface_t *surf) {
141  icon->icon_fetch_id = 0;
142  if (icon->icon) {
143  cairo_surface_destroy(icon->icon);
144  icon->icon = NULL;
145  }
146  if (surf) {
147  cairo_surface_reference(surf);
148  icon->icon = surf;
149  }
151 }
152 
153 icon *icon_create(widget *parent, const char *name) {
154  icon *b = g_malloc0(sizeof(icon));
155 
156  b->size = 16;
157  // Initialize widget.
158  widget_init(WIDGET(b), parent, WIDGET_TYPE_UNKNOWN, name);
159  b->widget.draw = icon_draw;
160  b->widget.free = icon_free;
164 
165  RofiDistance d = rofi_theme_get_distance(WIDGET(b), "size", b->size);
167 
168  b->squared = rofi_theme_get_boolean(WIDGET(b), "squared", TRUE);
169 
170  const char *filename = rofi_theme_get_string(WIDGET(b), "filename", NULL);
171  if (filename) {
172  b->icon_fetch_id = rofi_icon_fetcher_query(filename, b->size);
173  }
174  b->yalign = rofi_theme_get_double(WIDGET(b), "vertical-align", 0.5);
175  b->yalign = MAX(0, MIN(1.0, b->yalign));
176  b->xalign = rofi_theme_get_double(WIDGET(b), "horizontal-align", 0.5);
177  b->xalign = MAX(0, MIN(1.0, b->xalign));
178 
179  return b;
180 }
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, cairo_surface_t *surf)
Definition: icon.c:140
icon * icon_create(widget *parent, const char *name)
Definition: icon.c:153
void widget_queue_redraw(widget *wid)
Definition: widget.c:487
void widget_update(widget *widget)
Definition: widget.c:477
#define WIDGET(a)
Definition: widget.h:119
@ WIDGET_TYPE_UNKNOWN
Definition: widget.h:58
static int icon_get_desired_height(widget *widget, G_GNUC_UNUSED const int width)
Definition: icon.c:55
static void icon_free(widget *wid)
Definition: icon.c:121
static void icon_resize(widget *widget, short w, short h)
Definition: icon.c:131
static void icon_draw(widget *wid, cairo_t *draw)
Definition: icon.c:88
static int icon_get_desired_width(widget *widget, G_GNUC_UNUSED const int height)
Definition: icon.c:71
@ ROFI_ORIENTATION_VERTICAL
Definition: rofi-types.h:142
Definition: icon.c:39
double xalign
Definition: icon.c:49
int squared
Definition: icon.c:45
widget widget
Definition: icon.c:40
int size
Definition: icon.c:43
cairo_surface_t * icon
Definition: icon.c:52
uint32_t icon_fetch_id
Definition: icon.c:47
double yalign
Definition: icon.c:49
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)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition: theme.c:877
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
Definition: theme.c:903
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition: theme.c:1415
double rofi_theme_get_double(const widget *widget, const char *property, double def)
Definition: theme.c:1040
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
Definition: theme.c:990
void widget_init(widget *wid, widget *parent, WidgetType type, const char *name)
Definition: widget.c:34
int widget_padding_get_padding_width(const widget *wid)
Definition: widget.c:637
int widget_padding_get_left(const widget *wid)
Definition: widget.c:576
int widget_padding_get_right(const widget *wid)
Definition: widget.c:586
int widget_padding_get_padding_height(const widget *wid)
Definition: widget.c:631
int widget_padding_get_top(const widget *wid)
Definition: widget.c:598
int widget_padding_get_bottom(const widget *wid)
Definition: widget.c:608