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

View File

@ -36,6 +36,7 @@ namespace MIDI
tick_t duration;
int note;
int velocity;
bool selected;
};
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
* (may span octaves) */
void
@ -377,7 +430,7 @@ namespace MIDI
/** get timestamp of earliest selected event */
tick_t
event_list::selection_min ( void )
event_list::selection_min ( void ) const
{
FOR_SELECTED( e )
return e->timestamp();
@ -386,7 +439,7 @@ namespace MIDI
}
tick_t
event_list::selection_max ( void )
event_list::selection_max ( void ) const
{
RFOR_SELECTED( e )
return e->timestamp();
@ -396,7 +449,7 @@ namespace MIDI
/** move selected events by offset /o/ */
void
event_list::move_selected ( long o )
event_list::nudge_selected ( long o )
{
if ( o < 0 )
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
event_list::push_selection ( void )
{

View File

@ -57,12 +57,15 @@ namespace MIDI {
void select_all ( void );
void select_none ( 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 transpose_selected ( int n );
tick_t selection_min ( void );
tick_t selection_max ( void );
void move_selected ( long o );
tick_t selection_min ( void ) const;
tick_t selection_max ( void ) const;
void move_selected ( tick_t tick );
void nudge_selected ( long o );
void push_selection ( void );
void pop_selection ( void );
bool verify ( void ) const;
@ -81,7 +84,6 @@ namespace MIDI {
void rewrite_selected ( int from, int to );
void selected_hi_lo_note ( int *hi, int *lo ) const;
event_list & operator= ( const event_list &rhs );
event_list & operator= ( const list <midievent> &rhs );
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 )
{
_selection_mode = SELECT_NONE;
_move_mode = false;
{ Fl_Box *o = new Fl_Box( X, Y, W, H - 75 );
/* 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 */
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();
}
@ -255,7 +260,7 @@ Canvas::grid ( Grid *g )
redraw();
// parent()->redraw();
// signal_settings_change();
signal_settings_change();
}
/** 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 */
fl_font( FL_TIMES, 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, (div_w * w), h );
fl_color( FL_FOREGROUND_COLOR );
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 >= 0 ) */
/* { */
/* if ( p1 < p2 ) */
/* fl_color( FL_GREEN ); */
/* else */
/* fl_color( FL_RED ); */
if ( p1 != p2 )
{
if ( p1 >= 0 )
{
if ( p1 < p2 )
fl_color( fl_color_add_alpha( FL_GREEN, 100 ) );
else
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 < p1 ) */
/* fl_color( FL_GREEN ); */
/* else */
/* fl_color( FL_RED ); */
/* fl_rectf( x + (div_w * p2), y + h / 2, div_w, h / 2 ); */
}
if ( p2 >= 0 )
{
if ( p2 < p1 )
fl_color( fl_color_add_alpha( FL_GREEN, 100 ) );
else
fl_color( fl_color_add_alpha( FL_RED, 100 ) );
fl_rectf( x + (div_w * p2), y + h / 2, div_w, h / 2 );
/* } */
/* } */
}
}
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 )
{
fl_draw_box( FL_ROUNDED_BOX, x, y + 1, w, m.div_h - 1, color );
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 ));
@ -677,11 +693,29 @@ Canvas::draw_overlay ( void )
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();
panzoomer->draw_overlay();
fl_pop_clip();
}
/** draw only the playhead--without reexamining the grid */
@ -962,6 +996,12 @@ Canvas::is_row_press ( void ) const
return -1;
}
bool
Canvas::is_ruler_click ( void ) const
{
return Fl::event_y() < m.origin_y + m.margin_top;
}
void
Canvas::start_cursor ( int x, int y )
{
@ -971,7 +1011,9 @@ Canvas::start_cursor ( int x, int y )
m.ruler_drawn = false;
m.p1 = x;
m.p3 = ntr( y );
/* m.p3 = ntr( y ); */
_lr();
@ -987,7 +1029,8 @@ Canvas::end_cursor ( int x, int y )
m.ruler_drawn = false;
m.p2 = x;
m.p4 = ntr( y );
/* m.p4 = ntr( y ); */
_lr();
@ -1036,10 +1079,10 @@ Canvas::move_selected ( int dir, int n )
switch ( dir )
{
case RIGHT:
m.grid->move_selected( n );
m.grid->nudge_selected( n );
break;
case LEFT:
m.grid->move_selected( 0 - n );
m.grid->nudge_selected( 0 - n );
break;
case UP:
case DOWN:
@ -1158,6 +1201,27 @@ Canvas::duplicate_range ( void )
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
Canvas::row_compact ( int n )
{
@ -1289,12 +1353,18 @@ Canvas::notes ( void )
{
return m.grid->notes();
}
int
Canvas::handle ( int m )
{
Canvas *c = this;
static int last_move_x = 0;
static int last_move_y = 0;
static bool range_select;
int ow, oh;
int x, y;
@ -1307,9 +1377,6 @@ Canvas::handle ( int m )
static int drag_y;
static bool delete_note;
static note_properties *drag_note;
static int adjusting_velocity;
// static note_properties;
ow = c->grid()->viewport.w;
oh = c->grid()->viewport.h;
@ -1318,6 +1385,7 @@ Canvas::handle ( int m )
{
case FL_FOCUS:
case FL_UNFOCUS:
damage( FL_DAMAGE_ALL );
return 1;
case FL_ENTER:
case FL_LEAVE:
@ -1338,12 +1406,11 @@ Canvas::handle ( int m )
}
case FL_KEYBOARD:
{
/* if ( Fl::event_state() & FL_ALT || Fl::event_state() & FL_CTRL ) */
/* // this is more than a simple keypress. */
/* return 0; */
if ( Fl::event_state() & FL_CTRL )
{
switch ( Fl::event_key() )
@ -1459,12 +1526,40 @@ Canvas::handle ( int m )
}
case FL_PUSH:
{
Fl::focus(this);
switch ( Fl::event_button() )
{
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;
adjusting_velocity = 0;
if ( Fl::event_ctrl() )
{
@ -1497,12 +1592,20 @@ Canvas::handle ( int m )
if ( ! this->m.grid->is_set( dx,dy ))
{
ghost_note = new note_properties;
drag_note = new note_properties;
ghost_note->start = this->m.grid->x_to_ts( dx );
ghost_note->note = dy;
ghost_note->duration = this->m.grid->default_length();
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;
processed = 1;
@ -1510,13 +1613,26 @@ Canvas::handle ( int m )
}
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 );
note_properties np;
this->m.grid->get_note_properties( dx, dy, &np );
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 );
@ -1552,11 +1668,31 @@ Canvas::handle ( int m )
}
}
else
if ( Fl::event_state() & FL_SHIFT )
{
_selection_mode = SELECT_RECTANGLE;
{
c->end_cursor( x, y );
break;
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;
signal_settings_change();
return 1;
}
return 1;
break;
}
/* if ( Fl::event_state() & FL_SHIFT ) */
/* { */
/* c->end_cursor( x, y ); */
/* break; */
/* } */
break;
}
default:
@ -1565,63 +1701,156 @@ Canvas::handle ( int m )
break;
}
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;
int dy = y;
grid_pos( &dx, &dy );
grid()->select( beginx, endx, beginy, endy );
}
if ( IS_PATTERN && Fl::event_state() & ( FL_ALT | FL_CTRL ) )
c->randomize_row( y );
else
{
if ( delete_note )
{
_selection_mode = SELECT_NONE;
_selection_rect.x1 = 0;
_selection_rect.y1 = 0;
_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 );
if ( ghost_note )
{
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
if ( ghost_note )
{
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
delete ghost_note;
}
ghost_note = 0;
}
else
if ( ghost_note )
{
this->m.grid->put( this->m.grid->ts_to_x( ghost_note->start ),
ghost_note->note,
ghost_note->duration,
ghost_note->velocity);
delete ghost_note;
}
ghost_note = 0;
}
else
if ( ghost_note )
{
this->m.grid->put( this->m.grid->ts_to_x( ghost_note->start ),
ghost_note->note,
ghost_note->duration,
ghost_note->velocity);
delete_note = false;
delete_note = false;
delete ghost_note;
ghost_note = 0;
}
delete ghost_note;
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 )
delete drag_note;
drag_note = 0;
break;
damage(FL_DAMAGE_OVERLAY);
return 1;
}
default:
processed = 0;
break;
}
break;
case FL_DRAG:
if ( Fl::event_button1() )
{
int dx = x;
int dy = y;
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 )
{
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
@ -1635,8 +1864,6 @@ Canvas::handle ( int m )
if ( ody != dy )
{
adjusting_velocity = 1;
ghost_note->velocity =
drag_note->velocity +
( (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;
}
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
ghost_note->duration = this->m.grid->x_to_ts( dx ) - ghost_note->start;
}
else
ghost_note->duration = drag_note->duration;
damage_grid( ghost_note->start, ghost_note->note, ghost_note->duration, 1 );
delete_note = false;

View File

@ -35,7 +35,15 @@ class Fl_Slider;
class Canvas : public Fl_Group, public trackable
{
class Canvas_Panzoomer;
struct SelectionRect {
int x1,y1,x2,y2;
};
SelectionRect _selection_rect;
int _selection_mode;
bool _move_mode;
Canvas_Panzoomer *panzoomer;
Fl_Slider *vzoom;
@ -84,6 +92,7 @@ class Canvas : public Fl_Group, public trackable
uint p3, p4; /* row cursors */
} m;
bool is_ruler_click ( void ) const;
int rtn ( int r ) const;
int ntr ( int n ) const;
@ -104,15 +113,29 @@ class Canvas : public Fl_Group, public trackable
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 );
enum {
SELECT_NONE = 0,
SELECT_RECTANGLE,
SELECT_RANGE
};
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 };
signal <void> signal_settings_change;
Canvas ( int X, int Y, int W, int H, const char *L=0 );
virtual ~Canvas ( );
void cut ( void );
void paste ( void );
void redraw_playhead ( void );
void handle_event_change ( void );
void set ( int x, int y );

View File

@ -27,6 +27,8 @@
using namespace MIDI;
MIDI::event_list Grid::_clipboard;
Grid::Grid ( void )
{
_name = NULL;
@ -139,11 +141,13 @@ Grid::_event ( int x, int y, bool write ) const
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;
int note = y_to_note( y );
tick_t xt = x_to_ts( x );
for ( event *e = r->first(); e; e = e->next() )
{
@ -153,14 +157,14 @@ Grid::_event ( int x, int y, bool write ) const
if ( e->note() != note )
continue;
unsigned long ts = e->timestamp();
unsigned long l = 0;
tick_t ts = e->timestamp();
tick_t l = 0;
if ( e->linked() )
l = e->link()->timestamp() - ts;
else
WARNING( "found unlinked event... event list is corrupt." );
if ( xt >= ts && xt < ts + l )
// this is a little nasty
return const_cast<event *>(e);
@ -307,7 +311,8 @@ Grid::put ( int x, int y, tick_t l, int velocity )
event *off = new event;
// 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;
DMESSAGE( "put %d,%d", x, y );
@ -541,6 +546,37 @@ Grid::toggle_select ( int x, int y )
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/ */
void
@ -641,9 +677,8 @@ Grid::delete_selected ( void )
}
void
Grid::move_selected ( int l )
Grid::nudge_selected ( int l )
{
long o = x_to_ts( abs( l ) );
if ( l < 0 )
@ -651,6 +686,20 @@ Grid::move_selected ( int l )
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 );
_rw->events.move_selected( o );
@ -692,6 +741,11 @@ Grid::crop ( int l, int r, int t, int b )
unlock();
}
int
Grid::min_selected ( void ) const
{
return ts_to_x( _rd->events.selection_min() );
}
void
Grid::_relink ( void )
@ -732,14 +786,6 @@ Grid::print ( void ) const
void
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 );
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();
/* if ( tse >= start && ts <= end ) */
draw_note( // ts_to_x( ts ),
draw_note(
ts,
note_to_y( e->note() ),
tse - ts,
@ -812,16 +857,32 @@ Grid::length ( tick_t l )
unlock();
}
void
Grid::bars ( int n )
{
lock();
_rw->length = n * _bpb * PPQN;
_fix_length();
unlock();
// trim();
signal_events_change();
}
int
Grid::bars ( void ) const
{
return ts_to_x( _rd->length ) / (_ppqn * _bpb);
return beats() / _bpb;
}
int
Grid::beats ( void ) const
{
return ts_to_x( _rd->length ) / _ppqn;
return _rd->length / PPQN;
}
int
@ -842,21 +903,16 @@ Grid::ppqn ( void ) const
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
Grid::resolution ( unsigned int n )
{
/* if ( n < 4 ) */
/* ASSERTION( "bad resolution: %d", n ); */
float W = viewport.w / _ppqn;
// _ppqn = n / 4;
_ppqn = n;
DMESSAGE( "%d setting resolution to %d", n, _ppqn );
/* ensure that the correct number of bars are in the viewport */
viewport.w = _ppqn * _bpb * 2;
viewport.w = _ppqn * W;
signal_events_change();
signal_settings_change();
@ -865,7 +921,7 @@ Grid::resolution ( unsigned int n )
int
Grid::resolution ( void ) const
{
return _ppqn * 4;
return _ppqn;
}
int

View File

@ -100,6 +100,8 @@ struct Viewport {
class Grid : public trackable
{
static MIDI::event_list _clipboard;
protected:
unsigned int _height;
@ -161,7 +163,7 @@ public:
int y_to_note ( int y ) const;
int note_to_y ( int n ) 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 * clone ( void ) = 0;
@ -191,6 +193,8 @@ public:
void height ( int h );
tick_t length ( void ) const;
void length ( tick_t l );
void bars ( int n );
int bars ( void ) const;
int beats ( void ) const;
void trim ( void );
@ -212,6 +216,7 @@ public:
void delete_selected ( void );
void move_selected ( int l );
void nudge_selected ( int l );
void crop ( int l, int r );
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;
int min_selected ( void ) const;
void cut ( void );
void copy ( void );
void paste ( int offset );
virtual tick_t default_length ( void ) const
{
return PPQN;
@ -261,14 +272,10 @@ inline tick_t
Grid::x_to_ts ( unsigned long x ) const
{
return (x * PPQN) / _ppqn;
// return x * (PPQN / _ppqn);
}
inline unsigned long
inline double
Grid::ts_to_x ( tick_t ts ) const
{
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
xywh {1172 936 100 100} type Double visible
xywh {1242 936 100 100} type Double visible
} {
Fl_Slider progress {
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 );
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
} {
@ -412,7 +414,7 @@ if ( Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape )
if ( maybe_save_song() )
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 );}
code1 {o->draw_overlay_callback( &UI::draw_overlay, this );}
code2 {o->xclass( APP_NAME );}
@ -422,32 +424,33 @@ if ( maybe_save_song() )
xywh {0 25 865 65} box FLAT_BOX
} {
Fl_Group {} {open
xywh {665 36 195 52}
xywh {552 26 312 69}
code0 {o->resizable(0);}
} {
Fl_Value_Input {} {
label BPM
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) ) );}
code2 {o->value( transport.beats_per_minute );}
}
Fl_Group {} {
label {Time Sig.} open
xywh {756 67 64 21} labelsize 9
xywh {756 38 64 21} labelsize 9
} {
Fl_Value_Input {} {
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) ) );}
code1 {o->value( transport.beats_per_bar );}
}
Fl_Box {} {
label {/}
xywh {780 67 14 21}
xywh {780 38 14 21}
}
Fl_Value_Input {} {
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) ) );}
code1 {o->value( transport.beat_type );}
}
@ -458,7 +461,7 @@ if ( maybe_save_song() )
config.record_mode = (record_mode_e)o->value();
else
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 {} {
label Merge
@ -479,7 +482,7 @@ else
}
Fl_Choice playback_mode_menu {
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 {} {
label Pattern
@ -502,46 +505,40 @@ else
xywh {0 0 40 24} labelfont 3 labelsize 10
}
}
Fl_Choice edit_mode_menu {
label {Edit Mode}
xywh {665 36 85 19} box DOWN_BOX down_box BORDER_BOX color 37 labelsize 9 align 1
Fl_Pack {} {open
xywh {555 60 305 30} type HORIZONTAL
class Fl_Scalepack
} {
MenuItem {} {
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 {} {
Fl_Button {} {
label Sequence
callback {tabs->value( sequence_tab );
edit_menu->deactivate();
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 {} {
label Trigger
callback {song.play_mode = TRIGGER;}
xywh {35 35 40 25} labelfont 3 labelsize 10 hide deactivate
Fl_Button {} {
label Phrase
callback {tabs->value( phrase_tab );
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 {
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 );}
class Visual_Metronome
} {}
@ -591,19 +588,19 @@ else
}
Fl_Tabs tabs {
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 );}
} {
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();}
} {
Fl_Group {} {open
xywh {10 118 233 502} labelsize 12
xywh {5 118 240 502} labelsize 12
} {
Fl_Browser playlist_browser {
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 };}
code1 {o->column_widths( widths ); o->column_char( '\\t' );}
code2 {o->value( 1 );}
@ -623,7 +620,7 @@ if ( val > 1 )
if ( ! playlist_browser->value() )
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 {
label Up
@ -633,7 +630,7 @@ if ( val > 1 )
playlist_browser->value( playlist_browser->value() - 1 );
update_sequence_widgets();
}}
xywh {97 559 65 25} shortcut 0xffbf
xywh {135 559 45 25} shortcut 0xffbf
}
Fl_Button sequence_phrase_down_button {
label Down
@ -643,7 +640,7 @@ if ( val > 1 )
playlist_browser->value( playlist_browser->value() + 1 );
update_sequence_widgets();
}}
xywh {169 559 74 25} shortcut 0xffc0
xywh {185 559 58 25} shortcut 0xffc0
}
Fl_Menu_Button sequence_phrase_choice {
label {Insert Phrase}
@ -657,13 +654,13 @@ if ( val )
playlist_browser->value( playlist_browser->value() + 1 );
else
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 {
label {name:}
label Name
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 {
label Detach
@ -683,17 +680,17 @@ else
sequence_tab->resize( pattern_tab->x(), pattern_tab->y(), pattern_tab->w(), pattern_tab->h() );
tabs->do_callback();
}}
xywh {7 733 78 26}
xywh {7 749 78 26}
}
Fl_Text_Editor sequence_notes_edit {
label {Notes:}
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 );}
}
Fl_Box triggers_widget {
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 );}
code1 {o->rows( 32 );}
class Triggers
@ -722,17 +719,17 @@ if ( playlist->length() )
}
}
}
Fl_Group phrase_tab {open
xywh {0 91 865 678} box FLAT_BOX color 47 labeltype NO_LABEL hide
Fl_Group phrase_tab {
xywh {0 91 865 693} box FLAT_BOX color 47 labeltype NO_LABEL hide
code0 {update_phrase_widgets();}
} {
Fl_Box phrase_canvas_widget {
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
}
Fl_Group {} {open
xywh {5 690 856 77} box FLAT_BOX color 47
Fl_Group phrase_settings_group {open
xywh {0 728 865 55} box FLAT_BOX color 47
} {
Fl_Input phrase_name_field {
label {name:}
@ -740,38 +737,38 @@ if ( playlist->length() )
// if the name changed..
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 );}
class Fl_Sometimes_Input
}
Fl_Light_Button phrase_mute_button {
label Mute
xywh {5 733 93 23} color 37 hide
xywh {0 751 93 23} color 37 hide
}
Fl_Light_Button phrase_solo_button {
label Solo
xywh {111 733 87 23} color 37 hide
xywh {106 751 87 23} color 37 hide
}
Fl_Text_Editor phrase_notes_edit {
label {Notes:}
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 );}
}
Fl_Value_Slider phrase_number_spinner {
label Phrase
label {Phrase:}
callback {phrase *p = ((phrase *)phrase_canvas_widget->grid())->by_number( o->value() );
if ( p )
phrase_canvas_widget->grid( p );
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
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();}
} {
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
class Canvas
}
Fl_Group pattern_settings_group {
xywh {0 731 865 54} box FLAT_BOX color 47
Fl_Group pattern_settings_group {open
xywh {0 730 867 55} box FLAT_BOX color 47
} {
Fl_Input pattern_name_field {
label {name:}
callback {pattern_canvas_widget->grid()->name( strdup( o->value() ) );}
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 );}
class Fl_Sometimes_Input
}
Fl_Light_Button pattern_mute_button {
label Mute
callback {Grid *g = pattern_canvas_widget->grid();
Fl_Group {} {open
xywh {5 733 300 44}
code0 {o->resizable(0);}
} {
Fl_Input pattern_name_field {
label {name:}
callback {pattern_canvas_widget->grid()->name( strdup( o->value() ) );}
xywh {5 734 185 21} box BORDER_BOX color 49 labelsize 12 align 20 when 8 textsize 12 textcolor 55
code0 {o->up_box( FL_BORDER_BOX );}
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 );
o->value( g->mode() == MUTE );
pattern_solo_button->value( 0 );}
xywh {195 734 58 19} type Normal shortcut 0x6d color 37 labelsize 12
}
Fl_Light_Button pattern_solo_button {
label Solo
callback {Grid *g = pattern_canvas_widget->grid();
xywh {195 734 58 19} type Normal shortcut 0x6d color 37 labelsize 12
}
Fl_Light_Button pattern_solo_button {
label Solo
callback {Grid *g = pattern_canvas_widget->grid();
g->mode( g->mode() == SOLO ? PLAY : SOLO );
o->value( g->mode() == SOLO );
pattern_mute_button->value( 0 );}
xywh {195 758 58 19} type Normal shortcut 0x73 color 37 labelsize 12
}
Fl_Text_Editor pattern_notes_edit {
label {Notes:}
callback {pattern_canvas_widget->grid()->notes( o->buffer()->text() );}
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 );}
code1 {o->wrap_mode( Fl_Text_Editor::WRAP_AT_BOUNDS, 0 );}
xywh {195 758 58 19} type Normal shortcut 0x73 color 37 labelsize 12
}
Fl_Value_Slider pattern_number_spinner {
label Pattern
callback {pattern *p = ((pattern *)pattern_canvas_widget->grid())->by_number( o->value() );
if ( p )
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
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 {
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 {
label {@>}
@ -863,7 +860,7 @@ if ( 0 == strncmp( picked, "Scale", strlen( "Scale" ) ) )
pattern_key_combo->activate();
}} 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();}
} {
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() );
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 {} {
label C
@ -934,7 +931,7 @@ pattern_canvas_widget->changed_mapping();} open
Fl_Choice pattern_note_combo {
label {&Note 1/}
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 {} {
label 1
@ -984,7 +981,7 @@ pattern_canvas_widget->changed_mapping();} open
Fl_Choice pattern_res_combo {
label {&Resolution 1/}
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 {} {
label 1
@ -1035,24 +1032,28 @@ pattern_canvas_widget->changed_mapping();} open
xywh {100 100 40 25} labelsize 11
}
}
}
Fl_Value_Slider pattern_number_spinner {
label Pattern
callback {pattern *p = ((pattern *)pattern_canvas_widget->grid())->by_number( o->value() );
if ( p )
pattern_canvas_widget->grid( p );
update_pattern_widgets();
o->maximum( pattern::patterns() );
pattern_settings_group->redraw();}
xywh {45 759 140 18} type Horizontal labelsize 10 align 4 minimum 1 maximum 128 step 1 value 1
}
Fl_Button {} {
label Select
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
Fl_Choice pattern_channel_choice {
label {Channel:}
callback {((pattern *)pattern_canvas_widget->grid())->channel( o->value() );} open
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 ); }}
} {}
Fl_Choice pattern_port_choice {
label {Port:}
callback {((pattern *)pattern_canvas_widget->grid())->port( o->value() );} open
xywh {810 760 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 ); }}
} {}
Fl_Input_Choice pattern_bars_choice {
label {Bars:}
callback {((pattern *)pattern_canvas_widget->grid())->bars( atoi( o->value() ) );} open
xywh {486 736 55 19} labelsize 10 textsize 12
code0 {char pat[4]; for ( int i = 1; i <= 16; i++ ) { snprintf( pat, 3, "%i", i ); o->add( pat ); }}
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 {
label {&Edit} open
label {&Edit} open selected
xywh {0 0 68 18}
} {
MenuItem {} {
@ -1349,7 +1350,7 @@ else
{
phrase_number_spinner->value( min( 127, (int)phrase_number_spinner->value() + 1 ));
phrase_number_spinner->do_callback();
}} selected
}}
xywh {20 20 34 18} shortcut 0x5d
}
MenuItem {} {
@ -1362,16 +1363,6 @@ w->grid( w->grid()->clone() );
ui->update_sequence_widgets();}
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 {} {
label {Delete Selected}
callback {Canvas *w = current_canvas();
@ -1395,42 +1386,42 @@ w->grid()->clear();}
label {Select All}
callback {Canvas *w = current_canvas();
w->grid()->clear();}
w->grid()->select_all();}
xywh {70 70 34 18} shortcut 0x40061
}
MenuItem {} {
label {Select None}
callback {Canvas *w = current_canvas();
w->grid()->clear();}
w->grid()->select_none();}
xywh {80 80 34 18} shortcut 0x50061
}
MenuItem {} {
label {Invert Selection}
callback {Canvas *w = current_canvas();
w->grid()->clear();}
w->grid()->invert_selection();}
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 {} {
label Cut
callback {Canvas *w = current_canvas();
w->grid()->clear();}
w->cut();}
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 {} {
label Paste
callback {Canvas *w = current_canvas();
w->grid()->clear();}
w->paste();}
xywh {120 120 34 18} shortcut 0x40076
}
}
@ -1507,10 +1498,16 @@ if ( !g )
pattern_number_spinner->value( g->number() );
pattern_name_field->value( g->name() );
pattern_channel_spinner->value( 1 + g->channel() );
pattern_port_spinner->value( 1 + g->port() );
pattern_channel_choice->value( g->channel() );
pattern_port_choice->value( g->port() );
pattern_solo_button->value( g->mode() == SOLO );
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 )
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_res_combo->value( find_numeric_menu_item( menu_pattern_res_combo, g->resolution() ));
/*
if ( g->notes() )
pattern_notes_buffer->text( g->notes() );
else
pattern_notes_buffer->text( strdup( "" ) );} {}
pattern_notes_buffer->text( strdup( "" ) );
*/
pattern_settings_group->redraw();} {}
}
Function {update_phrase_widgets()} {open
} {
@ -1554,7 +1553,9 @@ phrase_mute_button->value( g->mode() == MUTE );
if ( g->notes() )
phrase_notes_buffer->text( g->notes() );
else
phrase_notes_buffer->text( strdup( "" ) );} {}
phrase_notes_buffer->text( strdup( "" ) );
phrase_settings_group->redraw();} {}
}
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 );
MESSAGE( "Relocating transport to %lu, %lu", ticks, frame );
MESSAGE( "Relocating transport to %f, %lu", ticks, frame );
jack_transport_locate( client, frame );
}