2 Epichord - a midi sequencer
3 Copyright (C) 2008 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
26 #include <fltk/Group.h>
27 #include <fltk/Widget.h>
28 #include <fltk/events.h>
41 extern struct conf config
;
45 Timeline::Timeline(int x
, int y
, int w
, int h
, const char* label
= 0) : fltk::Widget(x
, y
, w
, h
, label
) {
46 hand
= fltk::SharedImage::get(ROOT_DATA_DIR
"gfx/hand.gif");
48 printf("Timeline: gfx files not found, installed correctly?\n");
61 int Timeline::handle(int event
){
70 if(event_button() == 1){//set left limit
71 //pixel -> tick -> quantize -> global tick
72 tick
= quantize(xpix2tick(event_x())*scale
/4);
73 //printf("%d %d %d\n",tick,loop_start,loop_end);
74 if(tick
< get_loop_end()){
78 else if(event_button() == 2){//set song position
79 tick
= quantize(xpix2tick(event_x())*scale
/4);
80 //printf("%d %d %d\n",tick,loop_start,loop_end);
81 //pointer_x = tick2xpix(tick);
82 ui
->song_timeline
->update(tick
);
83 ui
->pattern_timeline
->update(tick
);
86 ui
->song_timeline
->redraw();
87 ui
->pattern_timeline
->redraw();
89 else if(event_button() == 3){//set right limit
90 tick
= quantize(xpix2tick(event_x())*scale
/4);
91 //printf("%d %d %d\n",tick,loop_start,loop_end);
92 if(tick
> get_loop_start()){
102 void Timeline::draw(){
104 fltk::setfont(fltk::HELVETICA
,12);
105 fltk::setcolor(fltk::WHITE
);
106 fltk::fillrect(0,0,w(),h());
108 fltk::push_clip(0,0,w(),h());
109 fltk::setcolor(fltk::BLACK
);
110 fltk::drawline(0,h()-1,w()-1,h()-1);
112 if(edit_flag
){//draw pattern timeline
114 int M
= config
.beats_per_measure
;
117 for(int i
=0; I
<w(); i
++){
120 fltk::fillrect(I
,h()/2,1,h()/2);
124 fltk::setcolor(fltk::BLACK
);
130 for(int i
=0; I
<w(); i
++){
131 I
= i
*zoom
*4 - scroll
;
133 fltk::fillrect(I
,0,1,h()/2);
134 sprintf(buf
,"%u",j
*label_scale
);
135 fltk::drawtext(buf
,I
+3,h()-3);
141 else{//draw song timeline
143 int M
= config
.beats_per_measure
;
144 int P
= config
.measures_per_phrase
;
146 for(int i
=0; I
<w(); i
++){
147 I
= i
*zoom
*M
/4 - scroll
;
149 fltk::fillrect(I
,h()/2,1,h()/2);
153 fltk::setcolor(fltk::BLACK
);
160 for(int i
=0; I
<w(); i
++){
161 I
= i
*zoom
*4*p
*M
/4/4 - scroll
;
163 fltk::fillrect(I
,0,1,h()/2);
164 sprintf(buf
,"%u",j
*label_scale
*p
/4);
165 fltk::drawtext(buf
,I
+3,h()-3);
172 int X
= tick2xpix(get_loop_start()*4/scale
);
174 fltk::setcolor(fltk::color(0,0,255));
175 fillrect(X
+0,0,1,h()-1);
176 fltk::setcolor(fltk::color(85,85,255));
177 fillrect(X
+1,0,1,h()-1);
178 fltk::setcolor(fltk::color(170,170,255));
179 fillrect(X
+2,0,1,h()-1);
182 X
= tick2xpix(get_loop_end()*4/scale
);
184 fltk::setcolor(fltk::color(128,0,0));
185 fillrect(X
+0,0,1,h()-1);
186 fltk::setcolor(fltk::color(170,42,42));
187 fillrect(X
-1,0,1,h()-1);
188 fltk::setcolor(fltk::color(255,170,170));
189 fillrect(X
-2,0,1,h()-1);
192 if(hand
&& pointer_x
*4/scale
-scroll
-10 >= -20){
193 hand
->draw(pointer_x
*4/scale
-scroll
-10,h()-19);
201 void Timeline::update(int ticks
){
202 //printf("%d\n",ticks);
203 pointer_x
= (ticks
/16 - ticks_offset
/16) * zoom
/ 8;
204 if(pointer_x
!= px_last
&& ticks
!= get_loop_end()){
210 int Timeline::tick2xpix(int tick
){
211 //return (tick - ticks_offset) * zoom / 128 - scroll;
212 return tick
* zoom
/ TICKS_PER_BEAT
- scroll
- ticks_offset
*zoom
/(32);
215 int Timeline::xpix2tick(int xpix
){
216 //return (xpix+scroll+ticks_offset*32/zoom)*128 / zoom;
217 return (xpix
+scroll
) * TICKS_PER_BEAT
/ zoom
+ ticks_offset
*120/30;
220 int Timeline::quantize(int tick
){
221 return tick
/TICKS_PER_BEAT
* TICKS_PER_BEAT
;