rofi  1.6.1
scrollbar.c
Go to the documentation of this file.
1 /*
2  * rofi
3  *
4  * MIT/X11 License
5  * Copyright © 2013-2020 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 <config.h>
29 #include <xkbcommon/xkbcommon.h>
30 #include <glib.h>
31 #include "widgets/textbox.h"
32 #include "widgets/icon.h"
33 #include "widgets/listview.h"
34 #include "widgets/scrollbar.h"
35 
36 #include "theme.h"
37 
39 #define DEFAULT_SCROLLBAR_WIDTH 8
40 
41 static void scrollbar_draw ( widget *, cairo_t * );
42 static void scrollbar_free ( widget * );
43 
45 {
46  // Want height we are.
47  return wid->h;
48 }
49 
50 // TODO
51 // This should behave more like a real scrollbar.
52 guint scrollbar_scroll_get_line ( const scrollbar *sb, int y )
53 {
54  y -= sb->widget.border.top.base.distance;
55  if ( y < 0 ) {
56  return 0;
57  }
58 
59  if ( y > sb->widget.h ) {
60  return sb->length - 1;
61  }
62 
63  short r = ( sb->length * sb->widget.h ) / ( (double) ( sb->length + sb->pos_length ) );
64  short handle = sb->widget.h - r;
65  double sec = ( ( r ) / (double) ( sb->length - 1 ) );
66  short half_handle = handle / 2;
67  y -= half_handle;
68  y = MIN ( MAX ( 0, y ), sb->widget.h - 2 * half_handle );
69 
70  unsigned int sel = ( ( y ) / sec );
71  return MIN ( sel, sb->length - 1 );
72 }
73 
74 static void scrollbar_scroll ( scrollbar *sb, int y )
75 {
77 }
78 
79 static WidgetTriggerActionResult scrollbar_trigger_action ( widget *wid, MouseBindingMouseDefaultAction action, G_GNUC_UNUSED gint x, gint y, G_GNUC_UNUSED void *user_data )
80 {
81  scrollbar *sb = (scrollbar *) wid;
82  switch ( action )
83  {
84  case MOUSE_CLICK_DOWN:
86  case MOUSE_CLICK_UP:
87  scrollbar_scroll ( sb, y );
89  case MOUSE_DCLICK_DOWN:
90  case MOUSE_DCLICK_UP:
91  break;
92  }
93  return FALSE;
94 }
95 
96 static gboolean scrollbar_motion_notify ( widget *wid, G_GNUC_UNUSED gint x, gint y )
97 {
98  scrollbar *sb = (scrollbar *) wid;
99  scrollbar_scroll ( sb, y );
100  return TRUE;
101 }
102 
103 scrollbar *scrollbar_create ( widget *parent, const char *name )
104 {
105  scrollbar *sb = g_malloc0 ( sizeof ( scrollbar ) );
106  widget_init ( WIDGET ( sb ), parent, WIDGET_TYPE_SCROLLBAR, name );
107  sb->widget.x = 0;
108  sb->widget.y = 0;
109  sb->width = rofi_theme_get_distance ( WIDGET ( sb ), "handle-width", DEFAULT_SCROLLBAR_WIDTH );
111  sb->widget.w = widget_padding_get_padding_width ( WIDGET ( sb ) ) + width;
113 
114  sb->widget.draw = scrollbar_draw;
115  sb->widget.free = scrollbar_free;
119 
120  sb->length = 10;
121  sb->pos = 0;
122  sb->pos_length = 4;
123 
124  return sb;
125 }
126 
127 static void scrollbar_free ( widget *wid )
128 {
129  scrollbar *sb = (scrollbar *) wid;
130  g_free ( sb );
131 }
132 
133 void scrollbar_set_max_value ( scrollbar *sb, unsigned int max )
134 {
135  if ( sb != NULL ) {
136  sb->length = MAX ( 1u, max );
137  }
138 }
139 
140 void scrollbar_set_handle ( scrollbar *sb, unsigned int pos )
141 {
142  if ( sb != NULL ) {
143  sb->pos = MIN ( sb->length, pos );
144  }
145 }
146 
147 void scrollbar_set_handle_length ( scrollbar *sb, unsigned int pos_length )
148 {
149  if ( sb != NULL ) {
150  sb->pos_length = MIN ( sb->length, MAX ( 1u, pos_length ) );
151  }
152 }
153 
166 static void scrollbar_draw ( widget *wid, cairo_t *draw )
167 {
168  scrollbar *sb = (scrollbar *) wid;
169  unsigned int wh = widget_padding_get_remaining_height ( wid );
170  // Calculate position and size.
171  unsigned int r = ( sb->length * wh ) / ( (double) ( sb->length + sb->pos_length ) );
172  unsigned int handle = wid->h - r;
173  double sec = ( ( r ) / (double) ( sb->length - 1 ) );
174  unsigned int height = handle;
175  unsigned int y = sb->pos * sec;
176  // Set max pos.
177  y = MIN ( y, wh - handle );
178  // Never go out of bar.
179  height = MAX ( 2, height );
180  // Cap length;
181  rofi_theme_get_color ( WIDGET ( sb ), "handle-color", draw );
182 
183  cairo_rectangle ( draw,
184  widget_padding_get_left ( wid ),
185  widget_padding_get_top ( wid ) + y,
187  height );
188  cairo_fill ( draw );
189 }
_scrollbar
Definition: scrollbar.h:44
WIDGET
#define WIDGET(a)
Definition: widget.h:115
rofi_theme_get_color
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
Definition: theme.c:861
scrollbar_scroll
static void scrollbar_scroll(scrollbar *sb, int y)
Definition: scrollbar.c:74
scrollbar_draw
static void scrollbar_draw(widget *, cairo_t *)
Definition: scrollbar.c:166
WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_END
@ WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_END
Definition: widget.h:86
scrollbar_get_desired_height
static int scrollbar_get_desired_height(widget *wid)
Definition: scrollbar.c:44
MOUSE_CLICK_UP
@ MOUSE_CLICK_UP
Definition: keyb.h:170
distance_get_pixel
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
Definition: theme.c:1026
_widget::get_desired_height
int(* get_desired_height)(struct _widget *)
Definition: widget-internal.h:81
rofi_theme_get_distance
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
Definition: theme.c:763
MOUSE_DCLICK_UP
@ MOUSE_DCLICK_UP
Definition: keyb.h:172
scrollbar_trigger_action
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
MOUSE_CLICK_DOWN
@ MOUSE_CLICK_DOWN
Definition: keyb.h:169
scrollbar_create
scrollbar * scrollbar_create(widget *parent, const char *name)
Definition: scrollbar.c:103
widget_padding_get_remaining_height
int widget_padding_get_remaining_height(const widget *wid)
Definition: widget.c:530
widget_padding_get_remaining_width
int widget_padding_get_remaining_width(const widget *wid)
Definition: widget.c:523
listview.h
_widget::draw
void(* draw)(struct _widget *widget, cairo_t *draw)
Definition: widget-internal.h:72
WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_BEGIN
@ WIDGET_TRIGGER_ACTION_RESULT_GRAB_MOTION_BEGIN
Definition: widget.h:84
MouseBindingMouseDefaultAction
MouseBindingMouseDefaultAction
Definition: keyb.h:168
theme.h
_widget::free
void(* free)(struct _widget *widget)
Definition: widget-internal.h:94
WIDGET_TYPE_SCROLLBAR
@ WIDGET_TYPE_SCROLLBAR
Definition: widget.h:67
_widget::trigger_action
widget_trigger_action_cb trigger_action
Definition: widget-internal.h:89
_widget::y
short y
Definition: widget-internal.h:42
scrollbar_set_handle_length
void scrollbar_set_handle_length(scrollbar *sb, unsigned int pos_length)
Definition: scrollbar.c:147
RofiDistanceUnit::distance
double distance
Definition: rofi-types.h:112
MOUSE_DCLICK_DOWN
@ MOUSE_DCLICK_DOWN
Definition: keyb.h:171
_widget::x
short x
Definition: widget-internal.h:40
_scrollbar::pos
unsigned int pos
Definition: scrollbar.h:47
widget_padding_get_top
int widget_padding_get_top(const widget *wid)
Definition: widget.c:502
_widget::parent
struct _widget * parent
Definition: widget-internal.h:64
icon.h
_listview
Definition: listview.c:71
scrollbar_set_max_value
void scrollbar_set_max_value(scrollbar *sb, unsigned int max)
Definition: scrollbar.c:133
scrollbar_motion_notify
static gboolean scrollbar_motion_notify(widget *wid, G_GNUC_UNUSED gint x, gint y)
Definition: scrollbar.c:96
scrollbar_set_handle
void scrollbar_set_handle(scrollbar *sb, unsigned int pos)
Definition: scrollbar.c:140
_widget::h
short h
Definition: widget-internal.h:46
_scrollbar::pos_length
unsigned int pos_length
Definition: scrollbar.h:48
_widget::motion_notify
gboolean(* motion_notify)(struct _widget *, gint x, gint y)
Definition: widget-internal.h:79
widget_init
void widget_init(widget *wid, widget *parent, WidgetType type, const char *name)
Definition: widget.c:74
_widget::w
short w
Definition: widget-internal.h:44
_widget::border
RofiPadding border
Definition: widget-internal.h:54
RofiPadding::top
RofiDistance top
Definition: rofi-types.h:163
textbox.h
_scrollbar::width
RofiDistance width
Definition: scrollbar.h:49
widget_padding_get_left
int widget_padding_get_left(const widget *wid)
Definition: widget.c:482
_scrollbar::length
unsigned int length
Definition: scrollbar.h:46
scrollbar_scroll_get_line
guint scrollbar_scroll_get_line(const scrollbar *sb, int y)
Definition: scrollbar.c:52
DEFAULT_SCROLLBAR_WIDTH
#define DEFAULT_SCROLLBAR_WIDTH
Definition: scrollbar.c:39
RofiDistance::base
RofiDistanceUnit base
Definition: rofi-types.h:129
ROFI_ORIENTATION_HORIZONTAL
@ ROFI_ORIENTATION_HORIZONTAL
Definition: rofi-types.h:140
listview_set_selected
void listview_set_selected(listview *lv, unsigned int selected)
Definition: listview.c:536
scrollbar_free
static void scrollbar_free(widget *)
Definition: scrollbar.c:127
widget_padding_get_padding_width
int widget_padding_get_padding_width(const widget *wid)
Definition: widget.c:544
_scrollbar::widget
widget widget
Definition: scrollbar.h:45
widget_padding_get_padding_height
int widget_padding_get_padding_height(const widget *wid)
Definition: widget.c:537
_widget
Definition: widget-internal.h:36
WidgetTriggerActionResult
WidgetTriggerActionResult
Definition: widget.h:78
scrollbar.h