forked from bvschaik/julius
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscrollbar.c
156 lines (142 loc) · 5.21 KB
/
scrollbar.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include "scrollbar.h"
#include "core/calc.h"
#include "core/image.h"
#include "core/image_group.h"
#include "graphics/image.h"
#include "graphics/image_button.h"
#define SCROLL_BUTTON_HEIGHT 26
#define SCROLL_BUTTON_WIDTH 39
#define SCROLL_DOT_SIZE 25
#define TOTAL_BUTTON_HEIGHT (2 * SCROLL_BUTTON_HEIGHT + SCROLL_DOT_SIZE)
static void text_scroll(int is_down, int num_lines);
static image_button image_button_scroll_up = {
0, 0, SCROLL_BUTTON_WIDTH, SCROLL_BUTTON_HEIGHT, IB_SCROLL,
GROUP_OK_CANCEL_SCROLL_BUTTONS, 8, text_scroll, button_none, 0, 1, 1
};
static image_button image_button_scroll_down = {
0, 0, SCROLL_BUTTON_WIDTH, SCROLL_BUTTON_HEIGHT, IB_SCROLL,
GROUP_OK_CANCEL_SCROLL_BUTTONS, 12, text_scroll, button_none, 1, 1, 1
};
static scrollbar_type *current;
void scrollbar_init(scrollbar_type *scrollbar, int scroll_position, int max_scroll_position)
{
if (max_scroll_position < 0) {
max_scroll_position = 0;
}
scrollbar->scroll_position = calc_bound(scroll_position, 0, max_scroll_position);
scrollbar->max_scroll_position = max_scroll_position;
scrollbar->is_dragging_scroll = 0;
}
void scrollbar_reset(scrollbar_type *scrollbar, int scroll_position)
{
scrollbar->scroll_position = scroll_position;
scrollbar->is_dragging_scroll = 0;
}
void scrollbar_update_max(scrollbar_type *scrollbar, int max_scroll_position)
{
if (max_scroll_position < 0) {
max_scroll_position = 0;
}
scrollbar->max_scroll_position = max_scroll_position;
if (scrollbar->scroll_position > max_scroll_position) {
scrollbar->scroll_position = max_scroll_position;
}
}
void scrollbar_draw(scrollbar_type *scrollbar)
{
if (scrollbar->max_scroll_position > 0 || scrollbar->always_visible) {
image_buttons_draw(scrollbar->x, scrollbar->y, &image_button_scroll_up, 1);
image_buttons_draw(scrollbar->x, scrollbar->y + scrollbar->height - SCROLL_BUTTON_HEIGHT,
&image_button_scroll_down, 1);
int pct;
if (scrollbar->scroll_position <= 0) {
pct = 0;
} else if (scrollbar->scroll_position >= scrollbar->max_scroll_position) {
pct = 100;
} else {
pct = calc_percentage(scrollbar->scroll_position, scrollbar->max_scroll_position);
}
int offset = calc_adjust_with_percentage(
scrollbar->height - TOTAL_BUTTON_HEIGHT - 2 * scrollbar->dot_padding, pct);
if (scrollbar->is_dragging_scroll) {
offset = scrollbar->scroll_position_drag;
}
image_draw(image_group(GROUP_PANEL_BUTTON) + 39,
scrollbar->x + (SCROLL_BUTTON_WIDTH - SCROLL_DOT_SIZE) / 2,
scrollbar->y + offset + SCROLL_BUTTON_HEIGHT + scrollbar->dot_padding);
}
}
static int handle_scrollbar_dot(scrollbar_type *scrollbar, const mouse *m)
{
if (scrollbar->max_scroll_position <= 0 || !m->left.is_down) {
return 0;
}
int track_height = scrollbar->height - TOTAL_BUTTON_HEIGHT - 2 * scrollbar->dot_padding;
if (m->x < scrollbar->x || m->x >= scrollbar->x + SCROLL_BUTTON_WIDTH) {
return 0;
}
if (m->y < scrollbar->y + SCROLL_BUTTON_HEIGHT + scrollbar->dot_padding ||
m->y > scrollbar->y + scrollbar->height - SCROLL_BUTTON_HEIGHT - scrollbar->dot_padding) {
return 0;
}
int dot_offset = m->y - scrollbar->y - SCROLL_DOT_SIZE/2 - SCROLL_BUTTON_HEIGHT;
if (dot_offset < 0) {
dot_offset = 0;
}
if (dot_offset > track_height) {
dot_offset = track_height;
}
int pct_scrolled = calc_percentage(dot_offset, track_height);
scrollbar->scroll_position = calc_adjust_with_percentage(
scrollbar->max_scroll_position, pct_scrolled);
scrollbar->is_dragging_scroll = 1;
scrollbar->scroll_position_drag = dot_offset;
if (scrollbar->scroll_position_drag < 0) {
scrollbar->scroll_position_drag = 0;
}
if (scrollbar->on_scroll_callback) {
scrollbar->on_scroll_callback();
}
return 1;
}
int scrollbar_handle_mouse(scrollbar_type *scrollbar, const mouse *m)
{
if (scrollbar->max_scroll_position <= 0) {
return 0;
}
current = scrollbar;
if (m->scrolled == SCROLL_DOWN) {
text_scroll(1, 3);
} else if (m->scrolled == SCROLL_UP) {
text_scroll(0, 3);
}
if (image_buttons_handle_mouse(m,
scrollbar->x, scrollbar->y, &image_button_scroll_up, 1, 0)) {
return 1;
}
if (image_buttons_handle_mouse(m,
scrollbar->x, scrollbar->y + scrollbar->height - SCROLL_BUTTON_HEIGHT,
&image_button_scroll_down, 1, 0)) {
return 1;
}
return handle_scrollbar_dot(scrollbar, m);
}
static void text_scroll(int is_down, int num_lines)
{
scrollbar_type *scrollbar = current;
if (is_down) {
scrollbar->scroll_position += num_lines;
if (scrollbar->scroll_position > scrollbar->max_scroll_position) {
scrollbar->scroll_position = scrollbar->max_scroll_position;
}
} else {
scrollbar->scroll_position -= num_lines;
if (scrollbar->scroll_position < 0) {
scrollbar->scroll_position = 0;
}
}
scrollbar->is_dragging_scroll = 0;
if (scrollbar->on_scroll_callback) {
scrollbar->on_scroll_callback();
}
}