rofi 2.0.0
scrollbar.c
Go to the documentation of this file.
1/*
2 * rofi
3 *
4 * MIT/X11 License
5 * Copyright © 2013-2023 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
28#include "widgets/scrollbar.h"
29#include "widgets/icon.h"
30#include "widgets/listview.h"
31#include "widgets/textbox.h"
32#include <glib.h>
33
34#include "theme.h"
35
37#define DEFAULT_SCROLLBAR_WIDTH 8
38
39static void scrollbar_draw(widget *, cairo_t *);
40static void scrollbar_free(widget *);
41
43 G_GNUC_UNUSED const int width) {
44 // Want height we are.
45 return wid->h;
46}
47
48// TODO
49// This should behave more like a real scrollbar.
50guint scrollbar_scroll_get_line(const scrollbar *sb, int y) {
51 y -= sb->widget.border.top.base.distance;
52 if (y < 0) {
53 return 0;
54 }
55
56 if (y > sb->widget.h) {
57 return sb->length - 1;
58 }
59
60 short r =
61 (sb->length * sb->widget.h) / ((double)(sb->length + sb->pos_length));
62 short handle = sb->widget.h - r;
63 double sec = ((r) / (double)(sb->length - 1));
64 short half_handle = handle / 2;
65 y -= half_handle;
66 y = MIN(MAX(0, y), sb->widget.h - 2 * half_handle);
67
68 unsigned int sel = ((y) / sec);
69 return MIN(sel, sb->length - 1);
70}
71
76
79 G_GNUC_UNUSED gint x, gint y,
80 G_GNUC_UNUSED void *user_data) {
81 scrollbar *sb = (scrollbar *)wid;
82 switch (action) {
85 case MOUSE_CLICK_UP:
86 scrollbar_scroll(sb, y);
89 case MOUSE_DCLICK_UP:
90 break;
91 }
92 return FALSE;
93}
94
95static gboolean scrollbar_motion_notify(widget *wid, G_GNUC_UNUSED gint x,
96 gint y) {
97 scrollbar *sb = (scrollbar *)wid;
98 scrollbar_scroll(sb, y);
99 return TRUE;
100}
101
102scrollbar *scrollbar_create(widget *parent, const char *name) {
103 scrollbar *sb = g_malloc0(sizeof(scrollbar));
104 widget_init(WIDGET(sb), parent, WIDGET_TYPE_SCROLLBAR, name);
105 sb->widget.x = 0;
106 sb->widget.y = 0;
107 sb->width = rofi_theme_get_distance(WIDGET(sb), "handle-width",
112
118
119 sb->length = 10;
120 sb->pos = 0;
121 sb->pos_length = 4;
122
123 return sb;
124}
125
126static void scrollbar_free(widget *wid) {
127 scrollbar *sb = (scrollbar *)wid;
128 g_free(sb);
129}
130
131void scrollbar_set_max_value(scrollbar *sb, unsigned int max) {
132 if (sb != NULL) {
133 sb->length = MAX(1u, max);
134 }
135}
136
137void scrollbar_set_handle(scrollbar *sb, unsigned int pos) {
138 if (sb != NULL) {
139 sb->pos = MIN(sb->length, pos);
140 }
141}
142
143void scrollbar_set_handle_length(scrollbar *sb, unsigned int pos_length) {
144 if (sb != NULL) {
145 sb->pos_length = MIN(sb->length, MAX(1u, pos_length));
146 }
147}
148
161static void scrollbar_draw(widget *wid, cairo_t *draw) {
162 scrollbar *sb = (scrollbar *)wid;
164 // Calculate position and size.
165 double r = (sb->length * wh) / ((double)(sb->length + sb->pos_length));
166 unsigned int handle = wid->h - r;
167 double sec = ((r) / (double)(sb->length - 1));
168 unsigned int height = handle;
169 unsigned int y = sb->pos * sec;
170 // Set max pos.
171 y = MIN(y, wh - handle);
172 // Never go out of bar.
173 height = MAX(2, height);
174 // Cap length;
175 rofi_theme_get_color(WIDGET(sb), "handle-color", draw);
176
177 if (rofi_theme_get_boolean(WIDGET(sb), "handle-rounded-corners", FALSE)) {
178 float x = widget_padding_get_left(wid);
179 float width = widget_padding_get_remaining_width(wid);
180
181 float radius = ((width < height) ? width : height) / 2; // Limit radius to prevent overlap
182
183 // Draw rounded rectangle
184 cairo_new_sub_path(draw);
185 cairo_arc(draw, x + width - radius, y + radius, radius, -G_PI_2, 0);
186 cairo_arc(draw, x + width - radius, y + height - radius, radius, 0, G_PI_2);
187 cairo_arc(draw, x + radius, y + height - radius, radius, G_PI_2, G_PI);
188 cairo_arc(draw, x + radius, y + radius, radius, G_PI, 1.5 * G_PI);
189 cairo_close_path(draw);
190
191 cairo_fill(draw);
192 }
193 else {
194 cairo_rectangle(draw, widget_padding_get_left(wid),
195 widget_padding_get_top(wid) + y,
197 cairo_fill(draw);
198 }
199}
MouseBindingMouseDefaultAction
Definition keyb.h:174
@ MOUSE_CLICK_DOWN
Definition keyb.h:175
@ MOUSE_DCLICK_UP
Definition keyb.h:178
@ MOUSE_CLICK_UP
Definition keyb.h:176
@ MOUSE_DCLICK_DOWN
Definition keyb.h:177
void scrollbar_set_max_value(scrollbar *sb, unsigned int max)
Definition scrollbar.c:131
struct _scrollbar scrollbar
scrollbar * scrollbar_create(widget *parent, const char *name)
Definition scrollbar.c:102
guint scrollbar_scroll_get_line(const scrollbar *sb, int y)
Definition scrollbar.c:50
void scrollbar_set_handle(scrollbar *sb, unsigned int pos)
Definition scrollbar.c:137
void scrollbar_set_handle_length(scrollbar *sb, unsigned int pos_length)
Definition scrollbar.c:143
struct _listview listview
Definition listview.h:45
void listview_set_selected(listview *lv, unsigned int selected)
Definition listview.c:646
struct _widget widget
Definition widget.h:49
#define WIDGET(a)
Definition widget.h:117
WidgetTriggerActionResult
Definition widget.h:74
@ WIDGET_TYPE_SCROLLBAR
Definition widget.h:64
@ WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_END
Definition widget.h:82
@ WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_BEGIN
Definition widget.h:80
@ ROFI_ORIENTATION_HORIZONTAL
Definition rofi-types.h:141
static void scrollbar_free(widget *)
Definition scrollbar.c:126
static void scrollbar_scroll(scrollbar *sb, int y)
Definition scrollbar.c:72
static int scrollbar_get_desired_height(widget *wid, G_GNUC_UNUSED const int width)
Definition scrollbar.c:42
static void scrollbar_draw(widget *, cairo_t *)
Definition scrollbar.c:161
#define DEFAULT_SCROLLBAR_WIDTH
Definition scrollbar.c:37
static gboolean scrollbar_motion_notify(widget *wid, G_GNUC_UNUSED gint x, gint y)
Definition scrollbar.c:95
static WidgetTriggerActionResult scrollbar_trigger_action(widget *wid, MouseBindingMouseDefaultAction action, G_GNUC_UNUSED gint x, gint y, G_GNUC_UNUSED void *user_data)
Definition scrollbar.c:78
RofiDistanceUnit base
Definition rofi-types.h:131
RofiDistance top
Definition rofi-types.h:208
RofiDistance width
Definition scrollbar.h:48
unsigned int pos_length
Definition scrollbar.h:47
unsigned int length
Definition scrollbar.h:45
unsigned int pos
Definition scrollbar.h:46
widget widget
Definition scrollbar.h:44
void(* free)(struct _widget *widget)
RofiPadding border
widget_trigger_action_cb trigger_action
int(* get_desired_height)(struct _widget *, const int width)
struct _widget * parent
void(* draw)(struct _widget *widget, cairo_t *draw)
gboolean(* motion_notify)(struct _widget *, gint x, gint y)
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition theme.c:1406
int rofi_theme_get_boolean(const widget *wid, const char *property, int def)
Definition theme.c:903
RofiDistance rofi_theme_get_distance(const widget *wid, const char *property, int def)
Definition theme.c:877
void rofi_theme_get_color(const widget *wid, const char *property, cairo_t *d)
Definition theme.c:1067
int widget_padding_get_remaining_width(const widget *wid)
Definition widget.c:619
void widget_init(widget *wid, widget *parent, WidgetType type, const char *name)
Definition widget.c:36
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_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_remaining_height(const widget *wid)
Definition widget.c:625