rofi  1.7.0
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  icon *b = (icon *)widget;
57  int height = b->size;
58  if (b->squared == FALSE) {
59  if (b->icon) {
60  int iconh = cairo_image_surface_get_height(b->icon);
61  int iconw = cairo_image_surface_get_width(b->icon);
62  int icons = MAX(iconh, iconw);
63  double scale = (double)b->size / icons;
64  height = iconh * scale;
65  }
66  }
68  return height;
69 }
71  icon *b = (icon *)widget;
72  int width = b->size;
73  if (b->squared == FALSE) {
74  if (b->icon) {
75  int iconh = cairo_image_surface_get_height(b->icon);
76  int iconw = cairo_image_surface_get_width(b->icon);
77  int icons = MAX(iconh, iconw);
78  double scale = (double)b->size / icons;
79  width = iconw * scale;
80  }
81  }
83  return width;
84 }
85 
86 static void icon_draw(widget *wid, cairo_t *draw) {
87  icon *b = (icon *)wid;
88  // If no icon is loaded. quit.
89  if (b->icon == NULL && b->icon_fetch_id > 0) {
91  if (b->icon) {
92  cairo_surface_reference(b->icon);
93  }
94  }
95  if (b->icon == NULL) {
96  return;
97  }
98  int iconh = cairo_image_surface_get_height(b->icon);
99  int iconw = cairo_image_surface_get_width(b->icon);
100  int icons = MAX(iconh, iconw);
101  double scale = (double)b->size / icons;
102 
103  int lpad = widget_padding_get_left(WIDGET(b));
104  int rpad = widget_padding_get_right(WIDGET(b));
105  int tpad = widget_padding_get_top(WIDGET(b));
106  int bpad = widget_padding_get_bottom(WIDGET(b));
107 
108  cairo_save(draw);
109 
110  cairo_translate(
111  draw, lpad + (b->widget.w - iconw * scale - lpad - rpad) * b->xalign,
112  tpad + (b->widget.h - iconh * scale - tpad - bpad) * b->yalign);
113  cairo_scale(draw, scale, scale);
114  cairo_set_source_surface(draw, b->icon, 0, 0);
115  cairo_paint(draw);
116  cairo_restore(draw);
117 }
118 
119 static void icon_free(widget *wid) {
120  icon *b = (icon *)wid;
121 
122  if (b->icon) {
123  cairo_surface_destroy(b->icon);
124  }
125 
126  g_free(b);
127 }
128 
129 static void icon_resize(widget *widget, short w, short h) {
130  icon *b = (icon *)widget;
131  if (b->widget.w != w || b->widget.h != h) {
132  b->widget.w = w;
133  b->widget.h = h;
135  }
136 }
137 
138 void icon_set_surface(icon *icon, cairo_surface_t *surf) {
139  icon->icon_fetch_id = 0;
140  if (icon->icon) {
141  cairo_surface_destroy(icon->icon);
142  icon->icon = NULL;
143  }
144  if (surf) {
145  cairo_surface_reference(surf);
146  icon->icon = surf;
147  }
149 }
150 
151 icon *icon_create(widget *parent, const char *name) {
152  icon *b = g_malloc0(sizeof(icon));
153 
154  b->size = 16;
155  // Initialize widget.
156  widget_init(WIDGET(b), parent, WIDGET_TYPE_UNKNOWN, name);
157  b->widget.draw = icon_draw;
158  b->widget.free = icon_free;
162 
163  RofiDistance d = rofi_theme_get_distance(WIDGET(b), "size", b->size);
165 
166  b->squared = rofi_theme_get_boolean(WIDGET(b), "squared", TRUE);
167 
168  const char *filename = rofi_theme_get_string(WIDGET(b), "filename", NULL);
169  if (filename) {
170  b->icon_fetch_id = rofi_icon_fetcher_query(filename, b->size);
171  }
172  b->yalign = rofi_theme_get_double(WIDGET(b), "vertical-align", 0.5);
173  b->yalign = MAX(0, MIN(1.0, b->yalign));
174  b->xalign = rofi_theme_get_double(WIDGET(b), "horizontal-align", 0.5);
175  b->xalign = MAX(0, MIN(1.0, b->xalign));
176 
177  return b;
178 }
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:138
icon * icon_create(widget *parent, const char *name)
Definition: icon.c:151
void widget_queue_redraw(widget *wid)
Definition: widget.c:509
void widget_update(widget *widget)
Definition: widget.c:499
#define WIDGET(a)
Definition: widget.h:119
@ WIDGET_TYPE_UNKNOWN
Definition: widget.h:58
static int icon_get_desired_width(widget *widget)
Definition: icon.c:70
static int icon_get_desired_height(widget *widget)
Definition: icon.c:55
static void icon_free(widget *wid)
Definition: icon.c:119
static void icon_resize(widget *widget, short w, short h)
Definition: icon.c:129
static void icon_draw(widget *wid, cairo_t *draw)
Definition: icon.c:86
@ ROFI_ORIENTATION_VERTICAL
Definition: rofi-types.h:135
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_height)(struct _widget *)
void(* draw)(struct _widget *widget, cairo_t *draw)
void(* resize)(struct _widget *, short, short)
int(* get_desired_width)(struct _widget *)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition: theme.c:830
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
Definition: theme.c:856
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition: theme.c:1282
double rofi_theme_get_double(const widget *widget, const char *property, double def)
Definition: theme.c:969
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
Definition: theme.c:941
void widget_init(widget *wid, widget *parent, WidgetType type, const char *name)
Definition: widget.c:44
int widget_padding_get_padding_width(const widget *wid)
Definition: widget.c:642
int widget_padding_get_left(const widget *wid)
Definition: widget.c:581
int widget_padding_get_right(const widget *wid)
Definition: widget.c:591
int widget_padding_get_padding_height(const widget *wid)
Definition: widget.c:636
int widget_padding_get_top(const widget *wid)
Definition: widget.c:603
int widget_padding_get_bottom(const widget *wid)
Definition: widget.c:613