Sequencer: GUI tweaks.

pull/116/head
Jonathan Moore Liles 2013-05-07 15:24:54 -07:00
parent 8055e08e9e
commit 451e948a17
10 changed files with 687 additions and 295 deletions

View File

@ -149,6 +149,7 @@ namespace MIDI
p->duration = note_duration(); p->duration = note_duration();
p->velocity = note_velocity(); p->velocity = note_velocity();
p->note = note(); p->note = note();
p->selected = selected();
} }
void void
@ -158,5 +159,6 @@ namespace MIDI
note_duration( p->duration ); note_duration( p->duration );
note_velocity( p->velocity ); note_velocity( p->velocity );
note( p->note ); note( p->note );
selected( p->selected );
} }
} }

View File

@ -36,6 +36,7 @@ namespace MIDI
tick_t duration; tick_t duration;
int note; int note;
int velocity; int velocity;
bool selected;
}; };
class event : public midievent class event : public midievent

View File

@ -350,6 +350,59 @@ namespace MIDI
} }
} }
/** copy selected events into event list /el/ */
void
event_list::copy_selected ( event_list *el ) const
{
event *fi = first();
if ( ! fi )
return;
tick_t offset = fi->timestamp();
FOR_SELECTED( e )
{
event *nel = 0;
if ( e->linked() )
nel = new event(*e->link());
event *ne = new event(*e);
ne->timestamp( ne->timestamp() - offset );
if ( nel )
{
nel->link( ne );
ne->link( nel );
nel->timestamp( nel->timestamp() - offset );
}
el->mix(ne);
}
}
/** add events from list /el/ */
void
event_list::paste ( tick_t offset, const event_list *el )
{
event *n;
for ( event *e = el->_head; e; e = n )
{
n = e->_next;
event *ne = new event(*e);
ne->link( NULL );
ne->timestamp( ne->timestamp() + offset );
insert( ne );
}
relink();
}
/** transpose selected notes (ignoring other event types) by /n/ tones /** transpose selected notes (ignoring other event types) by /n/ tones
* (may span octaves) */ * (may span octaves) */
void void
@ -377,7 +430,7 @@ namespace MIDI
/** get timestamp of earliest selected event */ /** get timestamp of earliest selected event */
tick_t tick_t
event_list::selection_min ( void ) event_list::selection_min ( void ) const
{ {
FOR_SELECTED( e ) FOR_SELECTED( e )
return e->timestamp(); return e->timestamp();
@ -386,7 +439,7 @@ namespace MIDI
} }
tick_t tick_t
event_list::selection_max ( void ) event_list::selection_max ( void ) const
{ {
RFOR_SELECTED( e ) RFOR_SELECTED( e )
return e->timestamp(); return e->timestamp();
@ -396,7 +449,7 @@ namespace MIDI
/** move selected events by offset /o/ */ /** move selected events by offset /o/ */
void void
event_list::move_selected ( long o ) event_list::nudge_selected ( long o )
{ {
if ( o < 0 ) if ( o < 0 )
if ( selection_min() < (tick_t)( 0 - o ) ) if ( selection_min() < (tick_t)( 0 - o ) )
@ -414,6 +467,31 @@ namespace MIDI
} }
} }
/** move block of selected events to tick /tick/ */
void
event_list::move_selected ( tick_t tick )
{
/* if ( o < 0 ) */
/* if ( selection_min() < (tick_t)( 0 - o ) ) */
/* return; */
tick_t min = selection_min();
tick_t offset = tick - min;
nudge_selected( offset );
/* FOR_SELECTED( e ) */
/* { */
/* e->timestamp( e->timestamp() + offset ); */
/* sort( e ); */
/* move( e, o ); */
/* } */
}
void void
event_list::push_selection ( void ) event_list::push_selection ( void )
{ {

View File

@ -57,12 +57,15 @@ namespace MIDI {
void select_all ( void ); void select_all ( void );
void select_none ( void ); void select_none ( void );
void invert_selection ( void ); void invert_selection ( void );
void copy_selected ( event_list *el ) const;
void paste ( tick_t offset, const event_list *el );
void remove_selected ( void ); void remove_selected ( void );
void transpose_selected ( int n ); void transpose_selected ( int n );
tick_t selection_min ( void ); tick_t selection_min ( void ) const;
tick_t selection_max ( void ); tick_t selection_max ( void ) const;
void move_selected ( long o ); void move_selected ( tick_t tick );
void nudge_selected ( long o );
void push_selection ( void ); void push_selection ( void );
void pop_selection ( void ); void pop_selection ( void );
bool verify ( void ) const; bool verify ( void ) const;
@ -81,7 +84,6 @@ namespace MIDI {
void rewrite_selected ( int from, int to ); void rewrite_selected ( int from, int to );
void selected_hi_lo_note ( int *hi, int *lo ) const; void selected_hi_lo_note ( int *hi, int *lo ) const;
event_list & operator= ( const event_list &rhs ); event_list & operator= ( const event_list &rhs );
event_list & operator= ( const list <midievent> &rhs ); event_list & operator= ( const list <midievent> &rhs );
event *operator[] ( unsigned int index ); event *operator[] ( unsigned int index );

View File

@ -154,6 +154,8 @@ static note_properties *ghost_note = 0;
Canvas::Canvas ( int X, int Y, int W, int H, const char *L ) : Fl_Group( X,Y,W,H,L ) Canvas::Canvas ( int X, int Y, int W, int H, const char *L ) : Fl_Group( X,Y,W,H,L )
{ {
_selection_mode = SELECT_NONE;
_move_mode = false;
{ Fl_Box *o = new Fl_Box( X, Y, W, H - 75 ); { Fl_Box *o = new Fl_Box( X, Y, W, H - 75 );
/* this is a dummy group where the canvas goes */ /* this is a dummy group where the canvas goes */
@ -218,7 +220,10 @@ Canvas::handle_event_change ( void )
/* mark the song as dirty and pass the signal on */ /* mark the song as dirty and pass the signal on */
song.set_dirty(); song.set_dirty();
// panzoomer->redraw(); Grid *g = grid();
panzoomer->x_value( g->x_to_ts( m.vp->x), g->x_to_ts( m.vp->w ), 0, g->length());
// panzoomer->redraw();
redraw(); redraw();
} }
@ -255,7 +260,7 @@ Canvas::grid ( Grid *g )
redraw(); redraw();
// parent()->redraw(); // parent()->redraw();
// signal_settings_change(); signal_settings_change();
} }
/** keep row compaction tables up-to-date */ /** keep row compaction tables up-to-date */
@ -401,6 +406,7 @@ gui_draw_ruler ( int x, int y, int w, int div_w, int div, int ofs, int p1, int p
{ {
/* Across the top */ /* Across the top */
fl_font( FL_TIMES, ruler_height ); fl_font( FL_TIMES, ruler_height );
int h = ruler_height; int h = ruler_height;
@ -412,6 +418,7 @@ gui_draw_ruler ( int x, int y, int w, int div_w, int div, int ofs, int p1, int p
// fl_rectf( x, y, x + (div_w * w), y + h ); // fl_rectf( x, y, x + (div_w * w), y + h );
fl_rectf( x, y, (div_w * w), h ); fl_rectf( x, y, (div_w * w), h );
fl_color( FL_FOREGROUND_COLOR ); fl_color( FL_FOREGROUND_COLOR );
fl_line( x + div_w / 2, y, x + div_w * w, y ); fl_line( x + div_w / 2, y, x + div_w * w, y );
@ -437,28 +444,28 @@ gui_draw_ruler ( int x, int y, int w, int div_w, int div, int ofs, int p1, int p
} }
} }
/* if ( p1 != p2 ) */ if ( p1 != p2 )
/* { */ {
/* if ( p1 >= 0 ) */ if ( p1 >= 0 )
/* { */ {
/* if ( p1 < p2 ) */ if ( p1 < p2 )
/* fl_color( FL_GREEN ); */ fl_color( fl_color_add_alpha( FL_GREEN, 100 ) );
/* else */ else
/* fl_color( FL_RED ); */ fl_color( fl_color_add_alpha( FL_GREEN, 100 ) );
/* fl_rectf( x + (div_w * p1), y + h / 2, div_w, h / 2 ); */ fl_rectf( x + (div_w * p1), y + h / 2, div_w, h / 2 );
/* } */ }
/* if ( p2 >= 0 ) */ if ( p2 >= 0 )
/* { */ {
/* if ( p2 < p1 ) */ if ( p2 < p1 )
/* fl_color( FL_GREEN ); */ fl_color( fl_color_add_alpha( FL_GREEN, 100 ) );
/* else */ else
/* fl_color( FL_RED ); */ fl_color( fl_color_add_alpha( FL_RED, 100 ) );
/* fl_rectf( x + (div_w * p2), y + h / 2, div_w, h / 2 ); */ fl_rectf( x + (div_w * p2), y + h / 2, div_w, h / 2 );
/* } */ }
/* } */ }
return h; return h;
} }
@ -614,8 +621,17 @@ Canvas::draw_dash ( tick_t x, int y, tick_t w, int color, int selected ) const
if ( w > 4 ) if ( w > 4 )
{ {
fl_draw_box( FL_ROUNDED_BOX, x, y + 1, w, m.div_h - 1, color ); fl_draw_box( FL_ROUNDED_BOX, x, y + 1, w, m.div_h - 1, color );
if ( selected ) if ( selected )
fl_draw_box( FL_ROUNDED_FRAME, x, y + 1, w, m.div_h - 1, FL_MAGENTA ); {
cairo_set_operator( Fl::cairo_cc(),CAIRO_OPERATOR_HSL_COLOR );
fl_draw_box( FL_ROUNDED_BOX, x, y + 1, w, m.div_h - 1, FL_MAGENTA );
cairo_set_operator( Fl::cairo_cc(),CAIRO_OPERATOR_OVER);
}
/* if ( selected ) */
/* fl_draw_box( FL_ROUNDED_FRAME, x, y + 1, w, m.div_h - 1, FL_MAGENTA ); */
} }
// fl_color_add_alpha( color, 170 )); // fl_color_add_alpha( color, 170 ));
@ -677,11 +693,29 @@ Canvas::draw_overlay ( void )
draw_playhead(); draw_playhead();
if ( _selection_mode )
{
int X,Y,W,H;
SelectionRect &s = _selection_rect;
X = s.x1 < s.x2 ? s.x1 : s.x2;
Y = s.y1 < s.y2 ? s.y1 : s.y2;
W = s.x1 < s.x2 ? s.x2 - s.x1 : s.x1 - s.x2;
H = s.y1 < s.y2 ? s.y2 - s.y1 : s.y1 - s.y2;
/* fl_rectf( X,Y,W,H, fl_color_add_alpha( FL_MAGENTA, 50 ) ); */
fl_rect( X,Y,W,H, FL_MAGENTA );
}
fl_pop_clip(); fl_pop_clip();
panzoomer->draw_overlay(); panzoomer->draw_overlay();
fl_pop_clip(); fl_pop_clip();
} }
/** draw only the playhead--without reexamining the grid */ /** draw only the playhead--without reexamining the grid */
@ -962,6 +996,12 @@ Canvas::is_row_press ( void ) const
return -1; return -1;
} }
bool
Canvas::is_ruler_click ( void ) const
{
return Fl::event_y() < m.origin_y + m.margin_top;
}
void void
Canvas::start_cursor ( int x, int y ) Canvas::start_cursor ( int x, int y )
{ {
@ -971,7 +1011,9 @@ Canvas::start_cursor ( int x, int y )
m.ruler_drawn = false; m.ruler_drawn = false;
m.p1 = x; m.p1 = x;
m.p3 = ntr( y );
/* m.p3 = ntr( y ); */
_lr(); _lr();
@ -987,7 +1029,8 @@ Canvas::end_cursor ( int x, int y )
m.ruler_drawn = false; m.ruler_drawn = false;
m.p2 = x; m.p2 = x;
m.p4 = ntr( y );
/* m.p4 = ntr( y ); */
_lr(); _lr();
@ -1036,10 +1079,10 @@ Canvas::move_selected ( int dir, int n )
switch ( dir ) switch ( dir )
{ {
case RIGHT: case RIGHT:
m.grid->move_selected( n ); m.grid->nudge_selected( n );
break; break;
case LEFT: case LEFT:
m.grid->move_selected( 0 - n ); m.grid->nudge_selected( 0 - n );
break; break;
case UP: case UP:
case DOWN: case DOWN:
@ -1158,6 +1201,27 @@ Canvas::duplicate_range ( void )
g->viewport.x = 0; g->viewport.x = 0;
} }
void
Canvas::cut ( void )
{
m.grid->cut();
}
void
Canvas::copy ( void )
{
m.grid->copy();
}
void
Canvas::paste ( void )
{
if ( m.p1 != m.p2 && m.p1 > m.vp->x && m.p1 < m.vp->x + m.vp->w )
m.grid->paste( m.p1 );
else
m.grid->paste( m.vp->x );
}
void void
Canvas::row_compact ( int n ) Canvas::row_compact ( int n )
{ {
@ -1290,11 +1354,17 @@ Canvas::notes ( void )
return m.grid->notes(); return m.grid->notes();
} }
int int
Canvas::handle ( int m ) Canvas::handle ( int m )
{ {
Canvas *c = this; Canvas *c = this;
static int last_move_x = 0;
static int last_move_y = 0;
static bool range_select;
int ow, oh; int ow, oh;
int x, y; int x, y;
@ -1307,9 +1377,6 @@ Canvas::handle ( int m )
static int drag_y; static int drag_y;
static bool delete_note; static bool delete_note;
static note_properties *drag_note; static note_properties *drag_note;
static int adjusting_velocity;
// static note_properties;
ow = c->grid()->viewport.w; ow = c->grid()->viewport.w;
oh = c->grid()->viewport.h; oh = c->grid()->viewport.h;
@ -1318,6 +1385,7 @@ Canvas::handle ( int m )
{ {
case FL_FOCUS: case FL_FOCUS:
case FL_UNFOCUS: case FL_UNFOCUS:
damage( FL_DAMAGE_ALL );
return 1; return 1;
case FL_ENTER: case FL_ENTER:
case FL_LEAVE: case FL_LEAVE:
@ -1343,7 +1411,6 @@ Canvas::handle ( int m )
/* // this is more than a simple keypress. */ /* // this is more than a simple keypress. */
/* return 0; */ /* return 0; */
if ( Fl::event_state() & FL_CTRL ) if ( Fl::event_state() & FL_CTRL )
{ {
switch ( Fl::event_key() ) switch ( Fl::event_key() )
@ -1459,12 +1526,40 @@ Canvas::handle ( int m )
} }
case FL_PUSH: case FL_PUSH:
{ {
Fl::focus(this);
switch ( Fl::event_button() ) switch ( Fl::event_button() )
{ {
case 1: case 1:
{ {
if ( is_ruler_click() )
{
c->start_cursor( x, y );
// return 1;
_selection_mode = SELECT_RANGE;
}
if ( _selection_mode )
{
drag_x = Fl::event_x();
drag_y = Fl::event_y();
_selection_rect.x1 = drag_x;
_selection_rect.y1 = drag_y;
_selection_rect.x2 = drag_x;
_selection_rect.y2 = drag_y;
if ( _selection_mode == SELECT_RANGE )
{
_selection_rect.y1 = 0;
_selection_rect.y2 = 2000;
}
return 1;
}
delete_note = true; delete_note = true;
adjusting_velocity = 0;
if ( Fl::event_ctrl() ) if ( Fl::event_ctrl() )
{ {
@ -1497,12 +1592,20 @@ Canvas::handle ( int m )
if ( ! this->m.grid->is_set( dx,dy )) if ( ! this->m.grid->is_set( dx,dy ))
{ {
ghost_note = new note_properties; ghost_note = new note_properties;
drag_note = new note_properties;
ghost_note->start = this->m.grid->x_to_ts( dx ); ghost_note->start = this->m.grid->x_to_ts( dx );
ghost_note->note = dy; ghost_note->note = dy;
ghost_note->duration = this->m.grid->default_length(); ghost_note->duration = this->m.grid->default_length();
ghost_note->velocity = 64; ghost_note->velocity = 64;
drag_note->start = this->m.grid->x_to_ts( dx );
drag_note->note = dy;
drag_note->duration = this->m.grid->default_length();
drag_note->velocity = 64;
delete_note = false; delete_note = false;
processed = 1; processed = 1;
@ -1510,13 +1613,26 @@ Canvas::handle ( int m )
} }
else else
{ {
ghost_note = new note_properties; note_properties np;
drag_note = new note_properties; this->m.grid->get_note_properties( dx, dy, &np );
this->m.grid->get_note_properties( dx, dy, ghost_note );
this->m.grid->get_note_properties( dx, dy, drag_note );
this->m.grid->del( dx, dy );
delete_note = true; if ( np.selected )
{
_move_mode = true;
/* initiate move */
last_move_x = dx;
last_move_y = ntr( dy );
}
else
{
ghost_note = new note_properties;
drag_note = new note_properties;
this->m.grid->get_note_properties( dx, dy, ghost_note );
this->m.grid->get_note_properties( dx, dy, drag_note );
this->m.grid->del( dx, dy );
delete_note = true;
}
} }
this->m.grid->get_start( &dx, &dy ); this->m.grid->get_start( &dx, &dy );
@ -1552,11 +1668,31 @@ Canvas::handle ( int m )
} }
} }
else else
if ( Fl::event_state() & FL_SHIFT ) {
_selection_mode = SELECT_RECTANGLE;
{ {
c->end_cursor( x, y ); drag_x = Fl::event_x();
break; drag_y = Fl::event_y();
_selection_rect.x1 = drag_x;
_selection_rect.y1 = drag_y;
_selection_rect.x2 = drag_x;
_selection_rect.y2 = drag_y;
signal_settings_change();
return 1;
} }
return 1;
break;
}
/* if ( Fl::event_state() & FL_SHIFT ) */
/* { */
/* c->end_cursor( x, y ); */
/* break; */
/* } */
break; break;
} }
default: default:
@ -1565,63 +1701,156 @@ Canvas::handle ( int m )
break; break;
} }
case FL_RELEASE: case FL_RELEASE:
switch ( Fl::event_button() ) {
_move_mode = false;
if ( SELECT_RANGE == _selection_mode )
{ {
case 1: select_range();
_selection_mode = SELECT_NONE;
return 1;
}
else if ( SELECT_RECTANGLE == _selection_mode )
{
int X,Y,W,H;
SelectionRect &s = _selection_rect;
X = s.x1 < s.x2 ? s.x1 : s.x2;
Y = s.y1 < s.y2 ? s.y1 : s.y2;
W = s.x1 < s.x2 ? s.x2 - s.x1 : s.x1 - s.x2;
H = s.y1 < s.y2 ? s.y2 - s.y1 : s.y1 - s.y2;
int endx = X + W;
int endy = Y + H;
int beginx = X;
int beginy = Y;
grid_pos( &beginx, &beginy );
grid_pos( &endx, &endy );
/* if ( is_ruler_click() ) */
/* { */
/* grid()->select( beginx, endx ); */
/* } */
/* else */
{ {
int dx = x; grid()->select( beginx, endx, beginy, endy );
int dy = y; }
grid_pos( &dx, &dy );
if ( IS_PATTERN && Fl::event_state() & ( FL_ALT | FL_CTRL ) ) _selection_mode = SELECT_NONE;
c->randomize_row( y );
else _selection_rect.x1 = 0;
{ _selection_rect.y1 = 0;
if ( delete_note ) _selection_rect.x2 = 0;
{ _selection_rect.y2 = 0;
damage(FL_DAMAGE_OVERLAY);
signal_settings_change();
return 1;
}
int dx = x;
int dy = y;
grid_pos( &dx, &dy );
if ( IS_PATTERN && Fl::event_state() & ( FL_ALT | FL_CTRL ) )
c->randomize_row( y );
else
{
if ( delete_note )
{
// this->m.grid->del( dx, dy ); // this->m.grid->del( dx, dy );
if ( ghost_note ) if ( ghost_note )
{ {
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 ); damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
delete ghost_note; delete ghost_note;
} }
ghost_note = 0; ghost_note = 0;
} }
else else
if ( ghost_note ) if ( ghost_note )
{ {
this->m.grid->put( this->m.grid->ts_to_x( ghost_note->start ), this->m.grid->put( this->m.grid->ts_to_x( ghost_note->start ),
ghost_note->note, ghost_note->note,
ghost_note->duration, ghost_note->duration,
ghost_note->velocity); ghost_note->velocity);
delete_note = false; delete_note = false;
delete ghost_note; delete ghost_note;
ghost_note = 0; ghost_note = 0;
} }
}
if ( drag_note )
delete drag_note;
drag_note = 0;
break;
}
case FL_DRAG:
if ( Fl::event_is_click() )
return 1;
{
if ( _selection_mode )
{
grid()->select_none();
_selection_rect.x2 = x;
_selection_rect.y2 = y;
if ( SELECT_RANGE == _selection_mode )
{
_selection_rect.y2 = 2000;
c->end_cursor( x, y );
} }
if ( drag_note ) damage(FL_DAMAGE_OVERLAY);
delete drag_note;
drag_note = 0;
break; return 1;
} }
default:
processed = 0;
break;
}
break;
case FL_DRAG:
if ( Fl::event_button1() )
{
int dx = x; int dx = x;
int dy = y; int dy = y;
grid_pos( &dx, &dy ); grid_pos( &dx, &dy );
if ( _move_mode )
{
int odx = drag_x;
int ody = drag_y;
grid_pos( &odx, &ody );
if ( last_move_x != dx )
{
//this->m.grid->move_selected( dx - move_xoffset );
if ( dx > last_move_x )
move_selected( RIGHT, dx - last_move_x );
else
move_selected( LEFT, last_move_x - dx );
}
dy = ntr( dy );
if ( dy != last_move_y )
{
if ( dy > last_move_y )
move_selected( DOWN, dy - last_move_y );
else
move_selected( UP, last_move_y - dy );
}
last_move_y = dy;
last_move_x = dx;
return 1;
}
if ( ghost_note ) if ( ghost_note )
{ {
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 ); damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
@ -1635,8 +1864,6 @@ Canvas::handle ( int m )
if ( ody != dy ) if ( ody != dy )
{ {
adjusting_velocity = 1;
ghost_note->velocity = ghost_note->velocity =
drag_note->velocity + drag_note->velocity +
( (drag_y - y) / 3.0f ); ( (drag_y - y) / 3.0f );
@ -1648,17 +1875,12 @@ Canvas::handle ( int m )
} }
} }
if ( ! adjusting_velocity ) if ( dx > this->m.grid->ts_to_x( ghost_note->start ) )
{ {
if ( dx > this->m.grid->ts_to_x( ghost_note->start ) ) ghost_note->duration = this->m.grid->x_to_ts( dx ) - ghost_note->start;
{
ghost_note->duration = this->m.grid->x_to_ts( dx ) - ghost_note->start;
}
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
} }
else
ghost_note->duration = drag_note->duration; damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
delete_note = false; delete_note = false;

View File

@ -36,6 +36,14 @@ class Canvas : public Fl_Group, public trackable
{ {
class Canvas_Panzoomer; class Canvas_Panzoomer;
struct SelectionRect {
int x1,y1,x2,y2;
};
SelectionRect _selection_rect;
int _selection_mode;
bool _move_mode;
Canvas_Panzoomer *panzoomer; Canvas_Panzoomer *panzoomer;
Fl_Slider *vzoom; Fl_Slider *vzoom;
@ -84,6 +92,7 @@ class Canvas : public Fl_Group, public trackable
uint p3, p4; /* row cursors */ uint p3, p4; /* row cursors */
} m; } m;
bool is_ruler_click ( void ) const;
int rtn ( int r ) const; int rtn ( int r ) const;
int ntr ( int n ) const; int ntr ( int n ) const;
@ -104,8 +113,20 @@ class Canvas : public Fl_Group, public trackable
static void draw_clip ( void *v, int X, int Y, int W, int H ); static void draw_clip ( void *v, int X, int Y, int W, int H );
void draw_clip ( int X, int Y, int W, int H ); void draw_clip ( int X, int Y, int W, int H );
enum {
SELECT_NONE = 0,
SELECT_RECTANGLE,
SELECT_RANGE
};
public: public:
bool selection_mode ( void ) const { return _selection_mode; }
void selection_mode ( bool b )
{
_selection_mode = b ? SELECT_RECTANGLE : SELECT_NONE;
}
enum { OFF, ON, TOGGLE }; enum { OFF, ON, TOGGLE };
signal <void> signal_settings_change; signal <void> signal_settings_change;
@ -113,6 +134,8 @@ public:
Canvas ( int X, int Y, int W, int H, const char *L=0 ); Canvas ( int X, int Y, int W, int H, const char *L=0 );
virtual ~Canvas ( ); virtual ~Canvas ( );
void cut ( void );
void paste ( void );
void redraw_playhead ( void ); void redraw_playhead ( void );
void handle_event_change ( void ); void handle_event_change ( void );
void set ( int x, int y ); void set ( int x, int y );

View File

@ -27,6 +27,8 @@
using namespace MIDI; using namespace MIDI;
MIDI::event_list Grid::_clipboard;
Grid::Grid ( void ) Grid::Grid ( void )
{ {
_name = NULL; _name = NULL;
@ -139,11 +141,13 @@ Grid::_event ( int x, int y, bool write ) const
const event_list *r = write ? &_rw->events : &d->events; const event_list *r = write ? &_rw->events : &d->events;
if ( r->empty() || x_to_ts( x ) > _rd->length ) tick_t xt = x_to_ts(x);
if ( r->empty() )
/* || xt > _rd->length ) */
return NULL; return NULL;
int note = y_to_note( y ); int note = y_to_note( y );
tick_t xt = x_to_ts( x );
for ( event *e = r->first(); e; e = e->next() ) for ( event *e = r->first(); e; e = e->next() )
{ {
@ -153,8 +157,8 @@ Grid::_event ( int x, int y, bool write ) const
if ( e->note() != note ) if ( e->note() != note )
continue; continue;
unsigned long ts = e->timestamp(); tick_t ts = e->timestamp();
unsigned long l = 0; tick_t l = 0;
if ( e->linked() ) if ( e->linked() )
l = e->link()->timestamp() - ts; l = e->link()->timestamp() - ts;
@ -307,7 +311,8 @@ Grid::put ( int x, int y, tick_t l, int velocity )
event *off = new event; event *off = new event;
// Don't allow overlap (Why not?) // Don't allow overlap (Why not?)
if ( _event( x, y, false ) || _event( x + xl - 1, y, false ) ) if ( _event( x, y, false ) ||
_event( x + xl, y, false ) )
return; return;
DMESSAGE( "put %d,%d", x, y ); DMESSAGE( "put %d,%d", x, y );
@ -541,6 +546,37 @@ Grid::toggle_select ( int x, int y )
unlock(); unlock();
} }
/** copy selected notes to clipboard */
void
Grid::copy ( void )
{
_rd->events.copy_selected( &_clipboard );
}
void
Grid::cut ( void )
{
_rd->events.copy_selected( &_clipboard );
lock();
_rw->events.remove_selected();
unlock();
}
void
Grid::paste ( int offset )
{
lock();
_rw->events.paste( x_to_ts( offset ), &_clipboard );
expand();
unlock();
}
/** insert /l/ ticks of time after /x/ */ /** insert /l/ ticks of time after /x/ */
void void
@ -641,9 +677,8 @@ Grid::delete_selected ( void )
} }
void void
Grid::move_selected ( int l ) Grid::nudge_selected ( int l )
{ {
long o = x_to_ts( abs( l ) ); long o = x_to_ts( abs( l ) );
if ( l < 0 ) if ( l < 0 )
@ -651,6 +686,20 @@ Grid::move_selected ( int l )
lock(); lock();
// MESSAGE( "moving by %ld", o );
_rw->events.nudge_selected( o );
unlock();
}
void
Grid::move_selected ( int l )
{
tick_t o = x_to_ts( l );
lock();
// MESSAGE( "moving by %ld", o ); // MESSAGE( "moving by %ld", o );
_rw->events.move_selected( o ); _rw->events.move_selected( o );
@ -692,6 +741,11 @@ Grid::crop ( int l, int r, int t, int b )
unlock(); unlock();
} }
int
Grid::min_selected ( void ) const
{
return ts_to_x( _rd->events.selection_min() );
}
void void
Grid::_relink ( void ) Grid::_relink ( void )
@ -732,14 +786,6 @@ Grid::print ( void ) const
void void
Grid::draw_notes ( draw_note_func_t draw_note, void *userdata ) const Grid::draw_notes ( draw_note_func_t draw_note, void *userdata ) const
{ {
/* int bx = viewport.x; */
/* int by = viewport.y; */
/* int bw = viewport.w + 100; /\* FIXME: hack *\/ */
/* int bh = viewport.h; */
/* const tick_t start = x_to_ts( bx ); */
/* const tick_t end = x_to_ts( bx + bw ); */
data *d = const_cast< data *>( _rd ); data *d = const_cast< data *>( _rd );
for ( const event *e = d->events.first(); e; e = e->next() ) for ( const event *e = d->events.first(); e; e = e->next() )
@ -753,8 +799,7 @@ Grid::draw_notes ( draw_note_func_t draw_note, void *userdata ) const
const tick_t tse = e->link()->timestamp(); const tick_t tse = e->link()->timestamp();
/* if ( tse >= start && ts <= end ) */ draw_note(
draw_note( // ts_to_x( ts ),
ts, ts,
note_to_y( e->note() ), note_to_y( e->note() ),
tse - ts, tse - ts,
@ -812,16 +857,32 @@ Grid::length ( tick_t l )
unlock(); unlock();
} }
void
Grid::bars ( int n )
{
lock();
_rw->length = n * _bpb * PPQN;
_fix_length();
unlock();
// trim();
signal_events_change();
}
int int
Grid::bars ( void ) const Grid::bars ( void ) const
{ {
return ts_to_x( _rd->length ) / (_ppqn * _bpb); return beats() / _bpb;
} }
int int
Grid::beats ( void ) const Grid::beats ( void ) const
{ {
return ts_to_x( _rd->length ) / _ppqn; return _rd->length / PPQN;
} }
int int
@ -842,20 +903,15 @@ Grid::ppqn ( void ) const
return _ppqn; return _ppqn;
} }
/** set grid resolution to /n/, where 0 is 1/4 note, 1 is 1/8 note 2 is 1/16 note, etc. */ /** set grid resolution to /n/, where /n/ is the denominator e.g. 1/n. */
void void
Grid::resolution ( unsigned int n ) Grid::resolution ( unsigned int n )
{ {
/* if ( n < 4 ) */ float W = viewport.w / _ppqn;
/* ASSERTION( "bad resolution: %d", n ); */
// _ppqn = n / 4;
_ppqn = n; _ppqn = n;
DMESSAGE( "%d setting resolution to %d", n, _ppqn );
/* ensure that the correct number of bars are in the viewport */ viewport.w = _ppqn * W;
viewport.w = _ppqn * _bpb * 2;
signal_events_change(); signal_events_change();
@ -865,7 +921,7 @@ Grid::resolution ( unsigned int n )
int int
Grid::resolution ( void ) const Grid::resolution ( void ) const
{ {
return _ppqn * 4; return _ppqn;
} }
int int

View File

@ -100,6 +100,8 @@ struct Viewport {
class Grid : public trackable class Grid : public trackable
{ {
static MIDI::event_list _clipboard;
protected: protected:
unsigned int _height; unsigned int _height;
@ -161,7 +163,7 @@ public:
int y_to_note ( int y ) const; int y_to_note ( int y ) const;
int note_to_y ( int n ) const; int note_to_y ( int n ) const;
tick_t x_to_ts ( unsigned long x ) const; tick_t x_to_ts ( unsigned long x ) const;
unsigned long ts_to_x ( tick_t ts ) const; double ts_to_x ( tick_t ts ) const;
virtual Grid * create ( void ) = 0; virtual Grid * create ( void ) = 0;
virtual Grid * clone ( void ) = 0; virtual Grid * clone ( void ) = 0;
@ -191,6 +193,8 @@ public:
void height ( int h ); void height ( int h );
tick_t length ( void ) const; tick_t length ( void ) const;
void length ( tick_t l ); void length ( tick_t l );
void bars ( int n );
int bars ( void ) const; int bars ( void ) const;
int beats ( void ) const; int beats ( void ) const;
void trim ( void ); void trim ( void );
@ -212,6 +216,7 @@ public:
void delete_selected ( void ); void delete_selected ( void );
void move_selected ( int l ); void move_selected ( int l );
void nudge_selected ( int l );
void crop ( int l, int r ); void crop ( int l, int r );
void crop ( int l, int r, int t, int b ); void crop ( int l, int r, int t, int b );
@ -237,6 +242,12 @@ public:
void get_note_properties ( int x, int y, MIDI::note_properties *p ) const; void get_note_properties ( int x, int y, MIDI::note_properties *p ) const;
int min_selected ( void ) const;
void cut ( void );
void copy ( void );
void paste ( int offset );
virtual tick_t default_length ( void ) const virtual tick_t default_length ( void ) const
{ {
return PPQN; return PPQN;
@ -261,14 +272,10 @@ inline tick_t
Grid::x_to_ts ( unsigned long x ) const Grid::x_to_ts ( unsigned long x ) const
{ {
return (x * PPQN) / _ppqn; return (x * PPQN) / _ppqn;
// return x * (PPQN / _ppqn);
} }
inline unsigned long inline double
Grid::ts_to_x ( tick_t ts ) const Grid::ts_to_x ( tick_t ts ) const
{ {
return (ts * _ppqn) / PPQN; return (ts * _ppqn) / PPQN;
// return ts / (PPQN / _ppqn);
} }

View File

@ -109,7 +109,7 @@ Function {init_colors()} {open private C return_type {static void}
} }
widget_class Visual_Metronome {open widget_class Visual_Metronome {open
xywh {1172 936 100 100} type Double visible xywh {1242 936 100 100} type Double visible
} { } {
Fl_Slider progress { Fl_Slider progress {
private xywh {139 115 1149 23} type Horizontal box FLAT_BOX color 7 selection_color 54 private xywh {139 115 1149 23} type Horizontal box FLAT_BOX color 7 selection_color 54
@ -362,7 +362,9 @@ Fl::visible_focus( 0 );
Fl::add_timeout( TRANSPORT_POLL_INTERVAL, update_transport ); Fl::add_timeout( TRANSPORT_POLL_INTERVAL, update_transport );
playlist->signal_new_song.connect( sigc::mem_fun( this, &UI::update_sequence_widgets ) );} {} playlist->signal_new_song.connect( sigc::mem_fun( this, &UI::update_sequence_widgets ) );
pattern_canvas_widget->signal_settings_change.connect( sigc::mem_fun( this, &UI::update_pattern_widgets ) );
phrase_canvas_widget->signal_settings_change.connect( sigc::mem_fun( this, &UI::update_phrase_widgets ) );} {}
} }
Function {~UI()} {open Function {~UI()} {open
} { } {
@ -412,7 +414,7 @@ if ( Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape )
if ( maybe_save_song() ) if ( maybe_save_song() )
quit();} open quit();} open
xywh {706 149 865 805} type Double color 47 resizable xywh {492 227 865 805} type Double color 47 resizable
code0 {o->color( FL_BACKGROUND_COLOR );} code0 {o->color( FL_BACKGROUND_COLOR );}
code1 {o->draw_overlay_callback( &UI::draw_overlay, this );} code1 {o->draw_overlay_callback( &UI::draw_overlay, this );}
code2 {o->xclass( APP_NAME );} code2 {o->xclass( APP_NAME );}
@ -422,32 +424,33 @@ if ( maybe_save_song() )
xywh {0 25 865 65} box FLAT_BOX xywh {0 25 865 65} box FLAT_BOX
} { } {
Fl_Group {} {open Fl_Group {} {open
xywh {665 36 195 52} xywh {552 26 312 69}
code0 {o->resizable(0);}
} { } {
Fl_Value_Input {} { Fl_Value_Input {} {
label BPM label BPM
callback {transport.set_beats_per_minute( o->value() );} callback {transport.set_beats_per_minute( o->value() );}
xywh {825 68 35 19} labelsize 9 align 1 when 8 textsize 10 xywh {825 39 35 19} labelsize 9 align 1 when 8 textsize 10
code1 {transport.signal_tempo_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );} code1 {transport.signal_tempo_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
code2 {o->value( transport.beats_per_minute );} code2 {o->value( transport.beats_per_minute );}
} }
Fl_Group {} { Fl_Group {} {
label {Time Sig.} open label {Time Sig.} open
xywh {756 67 64 21} labelsize 9 xywh {756 38 64 21} labelsize 9
} { } {
Fl_Value_Input {} { Fl_Value_Input {} {
callback {transport.set_beats_per_bar( o->value() );} callback {transport.set_beats_per_bar( o->value() );}
xywh {756 68 24 19} textsize 10 xywh {756 39 24 19} textsize 10
code0 {transport.signal_bpb_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );} code0 {transport.signal_bpb_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
code1 {o->value( transport.beats_per_bar );} code1 {o->value( transport.beats_per_bar );}
} }
Fl_Box {} { Fl_Box {} {
label {/} label {/}
xywh {780 67 14 21} xywh {780 38 14 21}
} }
Fl_Value_Input {} { Fl_Value_Input {} {
callback {transport.set_beat_type( o->value() );} callback {transport.set_beat_type( o->value() );}
xywh {795 68 24 19} textsize 10 xywh {795 39 24 19} textsize 10
code0 {transport.signal_beat_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );} code0 {transport.signal_beat_change.connect( sigc::mem_fun( o, static_cast<int (Fl_Valuator::*)(double)>(&Fl_Valuator::value) ) );}
code1 {o->value( transport.beat_type );} code1 {o->value( transport.beat_type );}
} }
@ -458,7 +461,7 @@ if ( maybe_save_song() )
config.record_mode = (record_mode_e)o->value(); config.record_mode = (record_mode_e)o->value();
else else
o->value( config.record_mode );} o->value( config.record_mode );}
xywh {755 36 105 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1 textsize 9 xywh {555 39 105 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1 textsize 9
} { } {
MenuItem {} { MenuItem {} {
label Merge label Merge
@ -479,7 +482,7 @@ else
} }
Fl_Choice playback_mode_menu { Fl_Choice playback_mode_menu {
label {Playback &Mode} label {Playback &Mode}
xywh {665 68 85 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1 xywh {665 39 85 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1
} { } {
MenuItem {} { MenuItem {} {
label Pattern label Pattern
@ -502,46 +505,40 @@ else
xywh {0 0 40 24} labelfont 3 labelsize 10 xywh {0 0 40 24} labelfont 3 labelsize 10
} }
} }
Fl_Choice edit_mode_menu { Fl_Pack {} {open
label {Edit Mode} xywh {555 60 305 30} type HORIZONTAL
xywh {665 36 85 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1 class Fl_Scalepack
} { } {
MenuItem {} { Fl_Button {} {
label Pattern
callback {tabs->value( pattern_tab );
edit_menu->activate();
menu_bar->redraw();}
xywh {15 15 40 25} shortcut 0x80031 labelfont 3 labelsize 10
}
MenuItem {} {
label Phrase
callback {tabs->value( phrase_tab );
edit_menu->activate();
menu_bar->redraw();}
xywh {25 25 40 25} shortcut 0x80032 labelfont 3 labelsize 11
}
MenuItem {} {
label Sequence label Sequence
callback {tabs->value( sequence_tab ); callback {tabs->value( sequence_tab );
edit_menu->deactivate(); edit_menu->deactivate();
menu_bar->redraw();} menu_bar->redraw();}
xywh {25 25 40 25} shortcut 0x80033 labelfont 3 labelsize 10 xywh {565 70 68 15} type Radio shortcut 0x80031 selection_color 69
} }
MenuItem {} { Fl_Button {} {
label Trigger label Phrase
callback {song.play_mode = TRIGGER;} callback {tabs->value( phrase_tab );
xywh {35 35 40 25} labelfont 3 labelsize 10 hide deactivate
edit_menu->activate();
menu_bar->redraw();}
xywh {575 80 68 5} type Radio shortcut 0x80032 selection_color 69
}
Fl_Button {} {
label Pattern
callback {tabs->value( pattern_tab );
edit_menu->activate();
menu_bar->redraw();}
xywh {585 90 68 0} type Radio shortcut 0x80033 value 1 selection_color 69
} }
} }
} }
Fl_Pack vmetro_widget { Fl_Pack vmetro_widget {
label Metronome label Metronome
xywh {160 27 500 60} type HORIZONTAL box UP_BOX color 40 selection_color 48 labelsize 33 align 0 resizable xywh {160 27 390 61} type HORIZONTAL box UP_BOX color 40 selection_color 48 labelsize 33 align 0 resizable
code0 {o->box( FL_FLAT_BOX );} code0 {o->box( FL_FLAT_BOX );}
class Visual_Metronome class Visual_Metronome
} {} } {}
@ -591,19 +588,19 @@ else
} }
Fl_Tabs tabs { Fl_Tabs tabs {
callback {((Fl_Group*)o->value())->child( 0 )->take_focus();} open callback {((Fl_Group*)o->value())->child( 0 )->take_focus();} open
xywh {0 91 865 694} box FLAT_BOX color 47 labeltype SHADOW_LABEL labelsize 19 when 1 resizable xywh {-1 91 868 694} box FLAT_BOX color 47 labeltype SHADOW_LABEL labelsize 19 when 1 resizable
code0 {canvas_background_color = fl_rgb_color( 18, 18, 18 );} code0 {canvas_background_color = fl_rgb_color( 18, 18, 18 );}
} { } {
Fl_Group sequence_tab {open Fl_Group sequence_tab {open
xywh {0 91 865 678} box FLAT_BOX color 37 labeltype NO_LABEL hide resizable xywh {0 91 865 692} box FLAT_BOX color 37 labeltype NO_LABEL labelsize 12 hide resizable
code0 {update_sequence_widgets();} code0 {update_sequence_widgets();}
} { } {
Fl_Group {} {open Fl_Group {} {open
xywh {10 118 233 502} labelsize 12 xywh {5 118 240 502} labelsize 12
} { } {
Fl_Browser playlist_browser { Fl_Browser playlist_browser {
label Playlist label Playlist
xywh {10 118 233 435} type Hold box EMBOSSED_BOX color 39 selection_color 30 labelcolor 55 align 1 when 4 textsize 18 textcolor 95 resizable xywh {5 155 240 398} type Hold box EMBOSSED_BOX color 39 selection_color 30 labelsize 12 labelcolor 55 align 1 when 4 textsize 18 textcolor 95 resizable
code0 {static int widths[] = { 40, 30, 0 };} code0 {static int widths[] = { 40, 30, 0 };}
code1 {o->column_widths( widths ); o->column_char( '\\t' );} code1 {o->column_widths( widths ); o->column_char( '\\t' );}
code2 {o->value( 1 );} code2 {o->value( 1 );}
@ -623,7 +620,7 @@ if ( val > 1 )
if ( ! playlist_browser->value() ) if ( ! playlist_browser->value() )
playlist_browser->value( playlist_browser->size() ); playlist_browser->value( playlist_browser->size() );
}} }}
xywh {14 559 73 25} shortcut 0xffff color 88 labelcolor 23 xywh {6 559 64 25} shortcut 0xffff color 88 labelcolor 23
} }
Fl_Button sequence_phrase_up_button { Fl_Button sequence_phrase_up_button {
label Up label Up
@ -633,7 +630,7 @@ if ( val > 1 )
playlist_browser->value( playlist_browser->value() - 1 ); playlist_browser->value( playlist_browser->value() - 1 );
update_sequence_widgets(); update_sequence_widgets();
}} }}
xywh {97 559 65 25} shortcut 0xffbf xywh {135 559 45 25} shortcut 0xffbf
} }
Fl_Button sequence_phrase_down_button { Fl_Button sequence_phrase_down_button {
label Down label Down
@ -643,7 +640,7 @@ if ( val > 1 )
playlist_browser->value( playlist_browser->value() + 1 ); playlist_browser->value( playlist_browser->value() + 1 );
update_sequence_widgets(); update_sequence_widgets();
}} }}
xywh {169 559 74 25} shortcut 0xffc0 xywh {185 559 58 25} shortcut 0xffc0
} }
Fl_Menu_Button sequence_phrase_choice { Fl_Menu_Button sequence_phrase_choice {
label {Insert Phrase} label {Insert Phrase}
@ -657,13 +654,13 @@ if ( val )
playlist_browser->value( playlist_browser->value() + 1 ); playlist_browser->value( playlist_browser->value() + 1 );
else else
playlist_browser->value( playlist_browser->size() );} open playlist_browser->value( playlist_browser->size() );} open
xywh {11 590 232 30} color 63 xywh {5 590 235 30} color 63
} {} } {}
} }
Fl_Input sequence_name_field { Fl_Input sequence_name_field {
label {name:} label Name
callback {playlist->name( o->value() );} callback {playlist->name( o->value() );}
xywh {91 733 158 26} color 36 align 20 when 1 textcolor 32 xywh {10 109 235 27} color 48 labelsize 12 align 1 when 1
} }
Fl_Light_Button detach_button { Fl_Light_Button detach_button {
label Detach label Detach
@ -683,17 +680,17 @@ else
sequence_tab->resize( pattern_tab->x(), pattern_tab->y(), pattern_tab->w(), pattern_tab->h() ); sequence_tab->resize( pattern_tab->x(), pattern_tab->y(), pattern_tab->w(), pattern_tab->h() );
tabs->do_callback(); tabs->do_callback();
}} }}
xywh {7 733 78 26} xywh {7 749 78 26}
} }
Fl_Text_Editor sequence_notes_edit { Fl_Text_Editor sequence_notes_edit {
label {Notes:} label {Notes:}
callback {playlist->notes( o->buffer()->text() );} callback {playlist->notes( o->buffer()->text() );}
xywh {254 684 606 73} selection_color 48 labelsize 12 align 5 textcolor 94 xywh {254 732 606 48} selection_color 48 labelsize 12 align 5 textcolor 94
code0 {o->buffer( sequence_notes_buffer = new Fl_Text_Buffer );} code0 {o->buffer( sequence_notes_buffer = new Fl_Text_Buffer );}
} }
Fl_Box triggers_widget { Fl_Box triggers_widget {
label Patterns label Patterns
xywh {253 118 607 549} box FLAT_BOX color 48 align 1 resizable xywh {253 118 607 598} box FLAT_BOX color 48 labelsize 12 align 1 resizable
code0 {o->color( FL_BACKGROUND_COLOR );} code0 {o->color( FL_BACKGROUND_COLOR );}
code1 {o->rows( 32 );} code1 {o->rows( 32 );}
class Triggers class Triggers
@ -722,17 +719,17 @@ if ( playlist->length() )
} }
} }
} }
Fl_Group phrase_tab {open Fl_Group phrase_tab {
xywh {0 91 865 678} box FLAT_BOX color 47 labeltype NO_LABEL hide xywh {0 91 865 693} box FLAT_BOX color 47 labeltype NO_LABEL hide
code0 {update_phrase_widgets();} code0 {update_phrase_widgets();}
} { } {
Fl_Box phrase_canvas_widget { Fl_Box phrase_canvas_widget {
label Phrase label Phrase
xywh {1 91 863 592} box FLAT_BOX color 37 labelsize 100 align 16 resizable xywh {0 91 865 637} box FLAT_BOX color 37 labelsize 100 align 16 resizable
class Canvas class Canvas
} }
Fl_Group {} {open Fl_Group phrase_settings_group {open
xywh {5 690 856 77} box FLAT_BOX color 47 xywh {0 728 865 55} box FLAT_BOX color 47
} { } {
Fl_Input phrase_name_field { Fl_Input phrase_name_field {
label {name:} label {name:}
@ -740,38 +737,38 @@ if ( playlist->length() )
// if the name changed.. // if the name changed..
update_sequence_widgets();} update_sequence_widgets();}
xywh {5 697 155 24} box ROUNDED_BOX color 49 labelfont 2 labelcolor 55 align 20 textfont 2 xywh {5 734 185 21} box ROUNDED_BOX color 49 labelfont 2 labelsize 12 labelcolor 55 align 20 textfont 2 textsize 12
code0 {o->up_box( FL_ROUNDED_BOX );} code0 {o->up_box( FL_ROUNDED_BOX );}
class Fl_Sometimes_Input class Fl_Sometimes_Input
} }
Fl_Light_Button phrase_mute_button { Fl_Light_Button phrase_mute_button {
label Mute label Mute
xywh {5 733 93 23} color 37 hide xywh {0 751 93 23} color 37 hide
} }
Fl_Light_Button phrase_solo_button { Fl_Light_Button phrase_solo_button {
label Solo label Solo
xywh {111 733 87 23} color 37 hide xywh {106 751 87 23} color 37 hide
} }
Fl_Text_Editor phrase_notes_edit { Fl_Text_Editor phrase_notes_edit {
label {Notes:} label {Notes:}
callback {phrase_canvas_widget->grid()->notes( o->buffer()->text() );} callback {phrase_canvas_widget->grid()->notes( o->buffer()->text() );}
xywh {170 702 685 58} selection_color 48 labelsize 12 textcolor 94 resizable xywh {200 742 660 36} selection_color 48 labelsize 12 textcolor 94 resizable
code0 {o->buffer( phrase_notes_buffer = new Fl_Text_Buffer );} code0 {o->buffer( phrase_notes_buffer = new Fl_Text_Buffer );}
} }
Fl_Value_Slider phrase_number_spinner { Fl_Value_Slider phrase_number_spinner {
label Phrase label {Phrase:}
callback {phrase *p = ((phrase *)phrase_canvas_widget->grid())->by_number( o->value() ); callback {phrase *p = ((phrase *)phrase_canvas_widget->grid())->by_number( o->value() );
if ( p ) if ( p )
phrase_canvas_widget->grid( p ); phrase_canvas_widget->grid( p );
o->maximum( phrase::phrases() );} o->maximum( phrase::phrases() );}
xywh {5 737 155 24} type Horizontal labelsize 10 align 1 minimum 1 maximum 128 step 1 value 1 textsize 14 xywh {45 760 140 18} type Horizontal labelsize 10 align 4 minimum 1 maximum 128 step 1 value 1 textsize 14
} }
} }
} }
Fl_Group pattern_tab {open Fl_Group pattern_tab {open
xywh {0 91 865 694} box FLAT_BOX color 47 labeltype NO_LABEL xywh {0 91 867 694} box FLAT_BOX color 47 labeltype NO_LABEL
code0 {update_pattern_widgets();} code0 {update_pattern_widgets();}
} { } {
Fl_Box pattern_canvas_widget { Fl_Box pattern_canvas_widget {
@ -779,64 +776,64 @@ o->maximum( phrase::phrases() );}
xywh {0 91 865 637} box FLAT_BOX color 37 labelsize 100 align 16 resizable xywh {0 91 865 637} box FLAT_BOX color 37 labelsize 100 align 16 resizable
class Canvas class Canvas
} }
Fl_Group pattern_settings_group { Fl_Group pattern_settings_group {open
xywh {0 731 865 54} box FLAT_BOX color 47 xywh {0 730 867 55} box FLAT_BOX color 47
} { } {
Fl_Input pattern_name_field { Fl_Group {} {open
label {name:} xywh {5 733 300 44}
callback {pattern_canvas_widget->grid()->name( strdup( o->value() ) );} code0 {o->resizable(0);}
xywh {5 734 185 21} box ROUNDED_BOX color 49 labelsize 12 align 20 when 8 textfont 2 textsize 12 textcolor 55 } {
code0 {o->up_box( FL_ROUNDED_BOX );} Fl_Input pattern_name_field {
class Fl_Sometimes_Input label {name:}
} callback {pattern_canvas_widget->grid()->name( strdup( o->value() ) );}
Fl_Light_Button pattern_mute_button { xywh {5 734 185 21} box BORDER_BOX color 49 labelsize 12 align 20 when 8 textsize 12 textcolor 55
label Mute code0 {o->up_box( FL_BORDER_BOX );}
callback {Grid *g = pattern_canvas_widget->grid(); class Fl_Sometimes_Input
}
Fl_Light_Button pattern_mute_button {
label Mute
callback {Grid *g = pattern_canvas_widget->grid();
g->mode( g->mode() == MUTE ? PLAY : MUTE ); g->mode( g->mode() == MUTE ? PLAY : MUTE );
o->value( g->mode() == MUTE ); o->value( g->mode() == MUTE );
pattern_solo_button->value( 0 );} pattern_solo_button->value( 0 );}
xywh {195 734 58 19} type Normal shortcut 0x6d color 37 labelsize 12 xywh {195 734 58 19} type Normal shortcut 0x6d color 37 labelsize 12
} }
Fl_Light_Button pattern_solo_button { Fl_Light_Button pattern_solo_button {
label Solo label Solo
callback {Grid *g = pattern_canvas_widget->grid(); callback {Grid *g = pattern_canvas_widget->grid();
g->mode( g->mode() == SOLO ? PLAY : SOLO ); g->mode( g->mode() == SOLO ? PLAY : SOLO );
o->value( g->mode() == SOLO ); o->value( g->mode() == SOLO );
pattern_mute_button->value( 0 );} pattern_mute_button->value( 0 );}
xywh {195 758 58 19} type Normal shortcut 0x73 color 37 labelsize 12 xywh {195 758 58 19} type Normal shortcut 0x73 color 37 labelsize 12
} }
Fl_Text_Editor pattern_notes_edit { Fl_Value_Slider pattern_number_spinner {
label {Notes:} label Pattern
callback {pattern_canvas_widget->grid()->notes( o->buffer()->text() );} callback {pattern *p = ((pattern *)pattern_canvas_widget->grid())->by_number( o->value() );
xywh {310 734 240 46} color 40 selection_color 48 labeltype NO_LABEL labelsize 10 textsize 11 textcolor 63 resizable
code0 {o->buffer( pattern_notes_buffer = new Fl_Text_Buffer );} if ( p )
code1 {o->wrap_mode( Fl_Text_Editor::WRAP_AT_BOUNDS, 0 );} pattern_canvas_widget->grid( p );
o->maximum( pattern::patterns() );}
xywh {45 759 140 18} type Horizontal labelsize 10 align 4 minimum 1 maximum 128 step 1 value 1
}
Fl_Button pattern_selection_mode {
label Select
callback {pattern_canvas_widget->selection_mode( o->value() );}
tooltip {Enable selection mode (you can also just hold down shift and drag the mouse)} xywh {260 733 45 44} type Toggle selection_color 5 labelsize 10
}
} }
Fl_Group {} {open Fl_Group {} {open
xywh {555 731 310 49} xywh {315 731 549 54}
} { } {
Fl_Spinner pattern_channel_spinner {
label Channel
callback {((pattern *)pattern_canvas_widget->grid())->channel( o->value() - 1 );}
xywh {820 735 40 19} color 36 labelsize 10 when 1 textsize 12
code0 {\#include "../pattern.H"}
code1 {o->maximum( 16 );}
}
Fl_Spinner pattern_port_spinner {
label Port
callback {((pattern *)pattern_canvas_widget->grid())->port( o->value() - 1 );}
xywh {820 758 40 19} color 36 labelsize 10 when 1 textsize 12
code0 {o->maximum( 16 );}
}
Fl_Output mapping_text { Fl_Output mapping_text {
label Mapping label Mapping
xywh {555 758 105 19} labelsize 10 align 20 textsize 11 xywh {535 761 105 19} labelsize 10 align 20 textsize 11
} }
Fl_Menu_Button mapping_menu { Fl_Menu_Button mapping_menu {
label {@>} label {@>}
@ -863,7 +860,7 @@ if ( 0 == strncmp( picked, "Scale", strlen( "Scale" ) ) )
pattern_key_combo->activate(); pattern_key_combo->activate();
}} open }} open
xywh {660 758 30 19} labeltype NO_LABEL labelsize 10 textsize 12 xywh {640 761 30 19} labeltype NO_LABEL labelsize 10 textsize 12
code0 {update_mapping_menu();} code0 {update_mapping_menu();}
} { } {
Submenu mapping_scale_menu { Submenu mapping_scale_menu {
@ -880,7 +877,7 @@ if ( 0 == strncmp( picked, "Scale", strlen( "Scale" ) ) )
callback {((pattern*)pattern_canvas_widget->grid())->mapping.key( o->value() ); callback {((pattern*)pattern_canvas_widget->grid())->mapping.key( o->value() );
pattern_canvas_widget->changed_mapping();} open pattern_canvas_widget->changed_mapping();} open
xywh {720 758 75 19} down_box BORDER_BOX labelsize 10 when 1 textsize 11 xywh {700 761 75 19} down_box BORDER_BOX labelsize 10 when 1 textsize 11
} { } {
MenuItem {} { MenuItem {} {
label C label C
@ -934,7 +931,7 @@ pattern_canvas_widget->changed_mapping();} open
Fl_Choice pattern_note_combo { Fl_Choice pattern_note_combo {
label {&Note 1/} label {&Note 1/}
callback {((pattern*)pattern_canvas_widget->grid())->note( atoi( o->menu()[ o->value() ].text ));} open callback {((pattern*)pattern_canvas_widget->grid())->note( atoi( o->menu()[ o->value() ].text ));} open
xywh {730 735 45 19} down_box BORDER_BOX labelsize 10 when 1 textsize 12 xywh {715 736 45 19} down_box BORDER_BOX labelsize 10 when 1 textsize 12
} { } {
MenuItem {} { MenuItem {} {
label 1 label 1
@ -984,7 +981,7 @@ pattern_canvas_widget->changed_mapping();} open
Fl_Choice pattern_res_combo { Fl_Choice pattern_res_combo {
label {&Resolution 1/} label {&Resolution 1/}
callback {pattern_canvas_widget->grid()->resolution( atoi( o->menu()[ o->value() ].text ));} open callback {pattern_canvas_widget->grid()->resolution( atoi( o->menu()[ o->value() ].text ));} open
xywh {625 735 55 19} down_box BORDER_BOX labelsize 10 when 1 textsize 12 xywh {615 736 55 19} down_box BORDER_BOX labelsize 10 when 1 textsize 12
} { } {
MenuItem {} { MenuItem {} {
label 1 label 1
@ -1035,24 +1032,28 @@ pattern_canvas_widget->changed_mapping();} open
xywh {100 100 40 25} labelsize 11 xywh {100 100 40 25} labelsize 11
} }
} }
} Fl_Choice pattern_channel_choice {
Fl_Value_Slider pattern_number_spinner { label {Channel:}
label Pattern callback {((pattern *)pattern_canvas_widget->grid())->channel( o->value() );} open
callback {pattern *p = ((pattern *)pattern_canvas_widget->grid())->by_number( o->value() ); xywh {810 735 47 19} down_box BORDER_BOX labelsize 10 textsize 12
code0 {char pat[3]; for ( int i = 1; i <= 16; i++ ) { snprintf( pat, 3, "%i", i ); o->add( pat ); }}
if ( p ) } {}
pattern_canvas_widget->grid( p ); Fl_Choice pattern_port_choice {
label {Port:}
update_pattern_widgets(); callback {((pattern *)pattern_canvas_widget->grid())->port( o->value() );} open
xywh {810 760 47 19} down_box BORDER_BOX labelsize 10 textsize 12
o->maximum( pattern::patterns() ); code0 {char pat[3]; for ( int i = 1; i <= 16; i++ ) { snprintf( pat, 3, "%i", i ); o->add( pat ); }}
} {}
pattern_settings_group->redraw();} Fl_Input_Choice pattern_bars_choice {
xywh {45 759 140 18} type Horizontal labelsize 10 align 4 minimum 1 maximum 128 step 1 value 1 label {Bars:}
} callback {((pattern *)pattern_canvas_widget->grid())->bars( atoi( o->value() ) );} open
Fl_Button {} { xywh {486 736 55 19} labelsize 10 textsize 12
label Select code0 {char pat[4]; for ( int i = 1; i <= 16; i++ ) { snprintf( pat, 3, "%i", i ); o->add( pat ); }}
tooltip {Enable selection mode (you can also just hold down shift and drag the mouse)} xywh {260 735 45 45} type Toggle selection_color 5 labelsize 10 code1 {for ( int i = 32; i <= 256; i <<= 1 ) { snprintf( pat, sizeof(pat), "%i", i ); o->add( pat ); }}
} {}
Fl_Box {} {
xywh {315 735 135 46} resizable
}
} }
} }
} }
@ -1310,7 +1311,7 @@ ab.run();}
} }
} }
Submenu edit_menu { Submenu edit_menu {
label {&Edit} open label {&Edit} open selected
xywh {0 0 68 18} xywh {0 0 68 18}
} { } {
MenuItem {} { MenuItem {} {
@ -1349,7 +1350,7 @@ else
{ {
phrase_number_spinner->value( min( 127, (int)phrase_number_spinner->value() + 1 )); phrase_number_spinner->value( min( 127, (int)phrase_number_spinner->value() + 1 ));
phrase_number_spinner->do_callback(); phrase_number_spinner->do_callback();
}} selected }}
xywh {20 20 34 18} shortcut 0x5d xywh {20 20 34 18} shortcut 0x5d
} }
MenuItem {} { MenuItem {} {
@ -1362,16 +1363,6 @@ w->grid( w->grid()->clone() );
ui->update_sequence_widgets();} ui->update_sequence_widgets();}
xywh {30 30 34 18} shortcut 0x64 xywh {30 30 34 18} shortcut 0x64
} }
MenuItem {} {
label {Duplicate Range}
callback {Canvas *w = current_canvas();
w->duplicate_range();
// number of phrases may have changed.
ui->update_sequence_widgets();}
xywh {40 40 34 18} shortcut 0x10064
}
MenuItem {} { MenuItem {} {
label {Delete Selected} label {Delete Selected}
callback {Canvas *w = current_canvas(); callback {Canvas *w = current_canvas();
@ -1395,42 +1386,42 @@ w->grid()->clear();}
label {Select All} label {Select All}
callback {Canvas *w = current_canvas(); callback {Canvas *w = current_canvas();
w->grid()->clear();} w->grid()->select_all();}
xywh {70 70 34 18} shortcut 0x40061 xywh {70 70 34 18} shortcut 0x40061
} }
MenuItem {} { MenuItem {} {
label {Select None} label {Select None}
callback {Canvas *w = current_canvas(); callback {Canvas *w = current_canvas();
w->grid()->clear();} w->grid()->select_none();}
xywh {80 80 34 18} shortcut 0x50061 xywh {80 80 34 18} shortcut 0x50061
} }
MenuItem {} { MenuItem {} {
label {Invert Selection} label {Invert Selection}
callback {Canvas *w = current_canvas(); callback {Canvas *w = current_canvas();
w->grid()->clear();} w->grid()->invert_selection();}
xywh {90 90 34 18} shortcut 0x50069 xywh {90 90 34 18} shortcut 0x50069
} }
MenuItem {} {
label Copy
callback {Canvas *w = current_canvas();
w->grid()->clear();}
xywh {100 100 34 18} shortcut 0x40063
}
MenuItem {} { MenuItem {} {
label Cut label Cut
callback {Canvas *w = current_canvas(); callback {Canvas *w = current_canvas();
w->grid()->clear();} w->cut();}
xywh {110 110 34 18} shortcut 0x40078 xywh {110 110 34 18} shortcut 0x40078
} }
MenuItem {} {
label Copy
callback {Canvas *w = current_canvas();
w->copy();}
xywh {100 100 34 18} shortcut 0x40063
}
MenuItem {} { MenuItem {} {
label Paste label Paste
callback {Canvas *w = current_canvas(); callback {Canvas *w = current_canvas();
w->grid()->clear();} w->paste();}
xywh {120 120 34 18} shortcut 0x40076 xywh {120 120 34 18} shortcut 0x40076
} }
} }
@ -1507,10 +1498,16 @@ if ( !g )
pattern_number_spinner->value( g->number() ); pattern_number_spinner->value( g->number() );
pattern_name_field->value( g->name() ); pattern_name_field->value( g->name() );
pattern_channel_spinner->value( 1 + g->channel() ); pattern_channel_choice->value( g->channel() );
pattern_port_spinner->value( 1 + g->port() ); pattern_port_choice->value( g->port() );
pattern_solo_button->value( g->mode() == SOLO ); pattern_solo_button->value( g->mode() == SOLO );
pattern_mute_button->value( g->mode() == MUTE ); pattern_mute_button->value( g->mode() == MUTE );
pattern_selection_mode->value( pattern_canvas_widget->selection_mode() );
{
char pat[5];
snprintf( pat, sizeof(pat), "%i", g->bars() );
pattern_bars_choice->value( pat );
}
if ( g->mapping.key() == -1 ) if ( g->mapping.key() == -1 )
pattern_key_combo->deactivate(); pattern_key_combo->deactivate();
@ -1526,11 +1523,13 @@ mapping_text->value( g->mapping.name() );
pattern_note_combo->value( find_numeric_menu_item( menu_pattern_note_combo, g->note() )); pattern_note_combo->value( find_numeric_menu_item( menu_pattern_note_combo, g->note() ));
pattern_res_combo->value( find_numeric_menu_item( menu_pattern_res_combo, g->resolution() )); pattern_res_combo->value( find_numeric_menu_item( menu_pattern_res_combo, g->resolution() ));
/*
if ( g->notes() ) if ( g->notes() )
pattern_notes_buffer->text( g->notes() ); pattern_notes_buffer->text( g->notes() );
else else
pattern_notes_buffer->text( strdup( "" ) );} {} pattern_notes_buffer->text( strdup( "" ) );
*/
pattern_settings_group->redraw();} {}
} }
Function {update_phrase_widgets()} {open Function {update_phrase_widgets()} {open
} { } {
@ -1554,7 +1553,9 @@ phrase_mute_button->value( g->mode() == MUTE );
if ( g->notes() ) if ( g->notes() )
phrase_notes_buffer->text( g->notes() ); phrase_notes_buffer->text( g->notes() );
else else
phrase_notes_buffer->text( strdup( "" ) );} {} phrase_notes_buffer->text( strdup( "" ) );
phrase_settings_group->redraw();} {}
} }
Function {update_sequence_widgets()} {open Function {update_sequence_widgets()} {open
} { } {

View File

@ -187,7 +187,7 @@ Transport::locate ( tick_t ticks )
{ {
jack_nframes_t frame = trunc( ticks * transport.frames_per_tick ); jack_nframes_t frame = trunc( ticks * transport.frames_per_tick );
MESSAGE( "Relocating transport to %lu, %lu", ticks, frame ); MESSAGE( "Relocating transport to %f, %lu", ticks, frame );
jack_transport_locate( client, frame ); jack_transport_locate( client, frame );
} }