-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathruler.cpp
More file actions
83 lines (76 loc) · 2.46 KB
/
ruler.cpp
File metadata and controls
83 lines (76 loc) · 2.46 KB
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
#pragma warning(push, 0)
#include <FL/fl_draw.H>
#pragma warning(pop)
#include <cstdio>
#include "ruler.h"
#include "main-window.h"
#include "themes.h"
Ruler::Ruler(int x, int y, int w, int h, const char *l) : Fl_Box(x, y, w, h, l) {}
int Ruler::handle(int event) {
Main_Window *mw = (Main_Window *)user_data();
if (event == FL_PUSH && Fl::event_button() == FL_RIGHT_MOUSE) {
mw->toggle_bookmark_from_x_pos(Fl::event_x());
return 1;
}
if ((event == FL_PUSH || (event == FL_DRAG && !mw->playing())) && Fl::event_button() != FL_RIGHT_MOUSE) {
mw->set_tick_from_x_pos(Fl::event_x());
return 1;
}
if (event == FL_ENTER && mw->song_loaded()) {
fl_cursor(FL_CURSOR_HAND);
return 1;
}
if (event == FL_LEAVE) {
fl_cursor(FL_CURSOR_DEFAULT);
return 1;
}
return Fl_Box::handle(event);
}
static inline void print_tick_label(char *s, size_t size, int n) {
snprintf(s, size, "%d", n);
}
void Ruler::draw() {
int X = x(), Y = y(), W = w(), H = h();
Main_Window *mw = (Main_Window *)user_data();
int px = mw->song_ticks_per_step() * TICK_WIDTHS[mw->zoom()+1];
int s = _options.steps_per_beat * px;
int S = _options.beats_per_measure * s;
int p = _options.pickup_offset * px + WHITE_KEY_WIDTH;
// background
fl_color(FL_DARK2);
fl_rectf(X, Y, W, H);
// edges
fl_color(OS::current_theme() == OS::Theme::HIGH_CONTRAST ? FL_SELECTION_COLOR : fl_color_average(FL_FOREGROUND_COLOR, FL_BACKGROUND_COLOR, 0.4f));
fl_xyline(X, Y+H-1, X+W-1);
// tick marks and labels
int mx = mw->song_scroll_x();
// tick marks
int o = (p / S + 1) * S - p;
int r = mx % s;
int n = mx / s + 1;
for (int i = s-r-1; i < W + o; i += s, n++) {
int d = (n % _options.beats_per_measure) ? H / 2 : 0;
fl_yxline(X+i - o, Y+d, Y+H-1);
}
// labels
char t[8] = {};
fl_font(FL_COURIER, 12);
fl_color(FL_FOREGROUND_COLOR);
fl_push_clip(X, Y, W, H);
int O = (p / S + 1) * S - p;
int R = mx % S;
int N = mx / S - p / S;
for (int i = S-R-1; i < W+S + O; i += S, N++) {
if (N >= 0) {
print_tick_label(t, sizeof(t), N);
fl_draw(t, X+i-S+1 - O, Y, S-2, H, FL_ALIGN_BOTTOM_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
}
}
fl_pop_clip();
fl_color(BOOKMARK_COLOR);
const std::set<int32_t> &bookmarks = mw->bookmarks();
for (int32_t bookmark : bookmarks) {
int x_pos = X + bookmark * TICK_WIDTHS[mw->zoom()+1] + WHITE_KEY_WIDTH - mx - 1;
fl_polygon(x_pos - 6, Y + H - 8, x_pos + 6, Y + H - 8, x_pos, Y + H - 2);
}
}