1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 #include "ui_scrollbar.h"
4 
5 #include <pobl/bl_debug.h>
6 
7 #include "cocoa.h"
8 
9 /* --- static functions --- */
10 
update_scroller(ui_scrollbar_t * sb)11 static void update_scroller(ui_scrollbar_t *sb) {
12   scroller_update(sb->window.my_window,
13                   sb->num_filled_log_lines == 0
14                       ? 1.0
15                       : ((float)(sb->current_row + sb->num_filled_log_lines)) /
16                             ((float)sb->num_filled_log_lines),
17                   ((float)sb->num_scr_lines) /
18                       ((float)(sb->num_filled_log_lines + sb->num_scr_lines)));
19 }
20 
21 /*
22  * callbacks of ui_window_t events.
23  */
24 
window_resized(ui_window_t * win)25 static void window_resized(ui_window_t *win) {
26   ui_scrollbar_t *sb;
27 
28 #ifdef __DEBUG
29   bl_debug_printf(BL_DEBUG_TAG " scrollbar resized.\n");
30 #endif
31 
32   sb = (ui_scrollbar_t*)win;
33 
34   sb->num_scr_lines = sb->window.height / sb->line_height;
35 
36   update_scroller(sb);
37 }
38 
39 /* --- global functions --- */
40 
ui_scrollbar_init(ui_scrollbar_t * sb,ui_scrollbar_event_listener_t * sb_listener,char * view_name,char * fg_color,char * bg_color,u_int height,u_int line_height,u_int num_log_lines,u_int num_filled_log_lines,int use_transbg,ui_picture_modifier_t * pic_mod)41 int ui_scrollbar_init(ui_scrollbar_t *sb, ui_scrollbar_event_listener_t *sb_listener,
42                       char *view_name, char *fg_color, char *bg_color, u_int height,
43                       u_int line_height, u_int num_log_lines, u_int num_filled_log_lines,
44                       int use_transbg, ui_picture_modifier_t *pic_mod) {
45   sb->view_name = "simple";
46   sb->view = NULL;
47   sb->fg_color = NULL;
48   sb->bg_color = NULL;
49 
50   sb->sb_listener = sb_listener;
51 
52   if (!ui_window_init(&sb->window, 10, height, 10, 0, 0, 0, 0, 0, 0, 0)) {
53     return 0;
54   }
55 
56   sb->line_height = line_height;
57   sb->num_scr_lines = height / line_height;
58   sb->num_log_lines = num_log_lines;
59   sb->num_filled_log_lines = num_filled_log_lines;
60 
61   sb->window.window_resized = window_resized;
62 
63   return 1;
64 }
65 
ui_scrollbar_final(ui_scrollbar_t * sb)66 void ui_scrollbar_final(ui_scrollbar_t *sb) {}
67 
ui_scrollbar_set_num_log_lines(ui_scrollbar_t * sb,u_int num_log_lines)68 void ui_scrollbar_set_num_log_lines(ui_scrollbar_t *sb, u_int num_log_lines) {
69   if (sb->num_log_lines == num_log_lines) {
70     return;
71   }
72 
73   sb->num_log_lines = num_log_lines;
74 
75   if (sb->num_filled_log_lines > sb->num_log_lines) {
76     sb->num_filled_log_lines = sb->num_log_lines;
77   }
78 
79   update_scroller(sb);
80 }
81 
ui_scrollbar_set_num_filled_log_lines(ui_scrollbar_t * sb,u_int lines)82 void ui_scrollbar_set_num_filled_log_lines(ui_scrollbar_t *sb, u_int lines) {
83   if (lines > sb->num_log_lines) {
84     lines = sb->num_log_lines;
85   }
86 
87   if (sb->num_filled_log_lines == lines) {
88     return;
89   }
90 
91   sb->num_filled_log_lines = lines;
92 
93   update_scroller(sb);
94 }
95 
ui_scrollbar_line_is_added(ui_scrollbar_t * sb)96 int ui_scrollbar_line_is_added(ui_scrollbar_t *sb) {
97   if ((*sb->sb_listener->screen_is_static)(sb->sb_listener->self)) {
98     if (sb->num_filled_log_lines < sb->num_log_lines) {
99       sb->num_filled_log_lines++;
100     }
101 
102     sb->current_row--;
103   } else if (sb->num_filled_log_lines == sb->num_log_lines) {
104     return 0;
105   } else {
106     sb->num_filled_log_lines++;
107   }
108 
109   update_scroller(sb);
110 
111   return 1;
112 }
113 
ui_scrollbar_reset(ui_scrollbar_t * sb)114 void ui_scrollbar_reset(ui_scrollbar_t *sb) {
115   sb->current_row = 0;
116 
117   update_scroller(sb);
118 }
119 
ui_scrollbar_move_upward(ui_scrollbar_t * sb,u_int size)120 int ui_scrollbar_move_upward(ui_scrollbar_t *sb, u_int size) {
121   /*
122    * XXX Adhoc solution
123    * Fix ui_screen.c:bs_{half_}page_{up|down}ward() instead.
124    */
125   if (sb->current_row + sb->num_filled_log_lines == 0) {
126     return 0;
127   }
128 
129   return ui_scrollbar_move(sb, sb->current_row - size);
130 }
131 
ui_scrollbar_move_downward(ui_scrollbar_t * sb,u_int size)132 int ui_scrollbar_move_downward(ui_scrollbar_t *sb, u_int size) {
133   if (sb->current_row >= 0) {
134     return 0;
135   }
136 
137   return ui_scrollbar_move(sb, sb->current_row + size);
138 }
139 
ui_scrollbar_move(ui_scrollbar_t * sb,int row)140 int ui_scrollbar_move(ui_scrollbar_t *sb, int row) {
141   if (0 < row) {
142     row = 0;
143   } else if (row + (int)sb->num_filled_log_lines < 0) {
144     row = -(sb->num_filled_log_lines);
145   }
146 
147   if (sb->current_row == row) {
148     return 0;
149   }
150 
151   sb->current_row = row;
152 
153   update_scroller(sb);
154 
155   return 1;
156 }
157 
ui_scrollbar_set_line_height(ui_scrollbar_t * sb,u_int line_height)158 int ui_scrollbar_set_line_height(ui_scrollbar_t *sb, u_int line_height) {
159   if (sb->line_height == line_height) {
160     return 0;
161   }
162 
163   sb->line_height = line_height;
164 
165   return 1;
166 }
167 
ui_scrollbar_set_fg_color(ui_scrollbar_t * sb,char * fg_color)168 int ui_scrollbar_set_fg_color(ui_scrollbar_t *sb, char *fg_color) { return 1; }
169 
ui_scrollbar_set_bg_color(ui_scrollbar_t * sb,char * bg_color)170 int ui_scrollbar_set_bg_color(ui_scrollbar_t *sb, char *bg_color) { return 1; }
171 
ui_scrollbar_change_view(ui_scrollbar_t * sb,char * name)172 int ui_scrollbar_change_view(ui_scrollbar_t *sb, char *name) { return 1; }
173 
ui_scrollbar_set_transparent(ui_scrollbar_t * sb,ui_picture_modifier_t * pic_mod,int force)174 int ui_scrollbar_set_transparent(ui_scrollbar_t *sb, ui_picture_modifier_t *pic_mod, int force) {
175   return 1;
176 }
177 
ui_scrollbar_unset_transparent(ui_scrollbar_t * sb)178 int ui_scrollbar_unset_transparent(ui_scrollbar_t *sb) { return 1; }
179 
ui_scrollbar_is_moved(ui_scrollbar_t * sb,float pos)180 void ui_scrollbar_is_moved(ui_scrollbar_t *sb, float pos) {
181   sb->current_row = sb->num_filled_log_lines * pos - sb->num_filled_log_lines;
182 
183   if (sb->sb_listener->screen_scroll_to) {
184     (*sb->sb_listener->screen_scroll_to)(sb->sb_listener->self, sb->current_row);
185   }
186 }
187