rofi 1.7.5
scrollbar.c
Go to the documentation of this file.
1/*
2 * rofi
3 *
4 * MIT/X11 License
5 * Copyright © 2013-2022 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#include <xkbcommon/xkbcommon.h>
34
35#include "theme.h"
36
38#define DEFAULT_SCROLLBAR_WIDTH 8
39
40static void scrollbar_draw(widget *, cairo_t *);
41static void scrollbar_free(widget *);
42
44 G_GNUC_UNUSED const int width) {
45 // Want height we are.
46 return wid->h;
47}
48
49// TODO
50// This should behave more like a real scrollbar.
51guint scrollbar_scroll_get_line(const scrollbar *sb, int y) {
52 y -= sb->widget.border.top.base.distance;
53 if (y < 0) {
54 return 0;
55 }
56
57 if (y > sb->widget.h) {
58 return sb->length - 1;
59 }
60
61 short r =
62 (sb->length * sb->widget.h) / ((double)(sb->length + sb->pos_length));
63 short handle = sb->widget.h - r;
64 double sec = ((r) / (double)(sb->length - 1));
65 short half_handle = handle / 2;
66 y -= half_handle;
67 y = MIN(MAX(0, y), sb->widget.h - 2 * half_handle);
68
69 unsigned int sel = ((y) / sec);
70 return MIN(sel, sb->length - 1);
71}
72
77
80 G_GNUC_UNUSED gint x, gint y,
81 G_GNUC_UNUSED void *user_data) {
82 scrollbar *sb = (scrollbar *)wid;
83 switch (action) {
86 case MOUSE_CLICK_UP:
87 scrollbar_scroll(sb, y);
90 case MOUSE_DCLICK_UP:
91 break;
92 }
93 return FALSE;
94}
95
96static gboolean scrollbar_motion_notify(widget *wid, G_GNUC_UNUSED gint x,
97 gint y) {
98 scrollbar *sb = (scrollbar *)wid;
99 scrollbar_scroll(sb, y);
100 return TRUE;
101}
102
103scrollbar *scrollbar_create(widget *parent, const char *name) {
104 scrollbar *sb = g_malloc0(sizeof(scrollbar));
105 widget_init(WIDGET(sb), parent, WIDGET_TYPE_SCROLLBAR, name);
106 sb->widget.x = 0;
107 sb->widget.y = 0;
108 sb->width = rofi_theme_get_distance(WIDGET(sb), "handle-width",
113
119
120 sb->length = 10;
121 sb->pos = 0;
122 sb->pos_length = 4;
123
124 return sb;
125}
126
127static void scrollbar_free(widget *wid) {
128 scrollbar *sb = (scrollbar *)wid;
129 g_free(sb);
130}
131
132void scrollbar_set_max_value(scrollbar *sb, unsigned int max) {
133 if (sb != NULL) {
134 sb->length = MAX(1u, max);
135 }
136}
137
138void scrollbar_set_handle(scrollbar *sb, unsigned int pos) {
139 if (sb != NULL) {
140 sb->pos = MIN(sb->length, pos);
141 }
142}
143
144void scrollbar_set_handle_length(scrollbar *sb, unsigned int pos_length) {
145 if (sb != NULL) {
146 sb->pos_length = MIN(sb->length, MAX(1u, pos_length));
147 }
148}
149
162static void scrollbar_draw(widget *wid, cairo_t *draw) {
163 scrollbar *sb = (scrollbar *)wid;
165 // Calculate position and size.
166 double r = (sb->length * wh) / ((double)(sb->length + sb->pos_length));
167 unsigned int handle = wid->h - r;
168 double sec = ((r) / (double)(sb->length - 1));
169 unsigned int height = handle;
170 unsigned int y = sb->pos * sec;
171 // Set max pos.
172 y = MIN(y, wh - handle);
173 // Never go out of bar.
174 height = MAX(2, height);
175 // Cap length;
176 rofi_theme_get_color(WIDGET(sb), "handle-color", draw);
177
178 cairo_rectangle(draw, widget_padding_get_left(wid),
179 widget_padding_get_top(wid) + y,
181 cairo_fill(draw);
182}
MouseBindingMouseDefaultAction
Definition keyb.h:168
@ MOUSE_CLICK_DOWN
Definition keyb.h:169
@ MOUSE_DCLICK_UP
Definition keyb.h:172
@ MOUSE_CLICK_UP
Definition keyb.h:170
@ MOUSE_DCLICK_DOWN
Definition keyb.h:171
void scrollbar_set_max_value(scrollbar *sb, unsigned int max)
Definition scrollbar.c:132
scrollbar * scrollbar_create(widget *parent, const char *name)
Definition scrollbar.c:103
guint scrollbar_scroll_get_line(const scrollbar *sb, int y)
Definition scrollbar.c:51
void scrollbar_set_handle(scrollbar *sb, unsigned int pos)
Definition scrollbar.c:138
void scrollbar_set_handle_length(scrollbar *sb, unsigned int pos_length)
Definition scrollbar.c:144
void listview_set_selected(listview *lv, unsigned int selected)
Definition listview.c:585
#define WIDGET(a)
Definition widget.h:119
WidgetTriggerActionResult
Definition widget.h:76
@ WIDGET_TYPE_SCROLLBAR
Definition widget.h:66
@ WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_END
Definition widget.h:84
@ WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_BEGIN
Definition widget.h:82
@ ROFI_ORIENTATION_HORIZONTAL
Definition rofi-types.h:143
static void scrollbar_free(widget *)
Definition scrollbar.c:127
static void scrollbar_scroll(scrollbar *sb, int y)
Definition scrollbar.c:73
static int scrollbar_get_desired_height(widget *wid, G_GNUC_UNUSED const int width)
Definition scrollbar.c:43
static void scrollbar_draw(widget *, cairo_t *)
Definition scrollbar.c:162
#define DEFAULT_SCROLLBAR_WIDTH
Definition scrollbar.c:38
static gboolean scrollbar_motion_notify(widget *wid, G_GNUC_UNUSED gint x, gint y)
Definition scrollbar.c:96
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:79
RofiDistanceUnit base
Definition rofi-types.h:133
RofiDistance top
Definition rofi-types.h:210
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)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition theme.c:877
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition theme.c:1415
void rofi_theme_get_color(const widget *widget, 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: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_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