2005-09-25 14:42:24 -04:00
/*
2009-10-14 12:10:01 -04:00
Copyright ( C ) 2003 Paul Davis
2005-09-25 14:42:24 -04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <cstdlib>
# include <cmath>
# include <algorithm>
# include <string>
# include <vector>
2009-02-25 13:26:51 -05:00
# include "pbd/error.h"
# include "pbd/stl_delete.h"
# include "pbd/whitespace.h"
2005-09-25 14:42:24 -04:00
2005-09-25 16:33:00 -04:00
# include <gtkmm2ext/utils.h>
# include <gtkmm2ext/selector.h>
# include <gtkmm2ext/gtk_ui.h>
# include <gtkmm2ext/choice.h>
2005-09-25 14:42:24 -04:00
2009-02-25 13:26:51 -05:00
# include "ardour/session.h"
# include "ardour/utils.h"
# include "ardour/processor.h"
# include "ardour/location.h"
2005-09-25 14:42:24 -04:00
# include "ardour_ui.h"
# include "public_editor.h"
# include "imageframe_time_axis.h"
# include "imageframe_time_axis_view.h"
# include "marker_time_axis_view.h"
# include "imageframe_view.h"
# include "marker_time_axis.h"
# include "marker_view.h"
# include "utils.h"
# include "prompter.h"
# include "rgb_macros.h"
2005-11-15 21:57:22 -05:00
# include "canvas_impl.h"
2005-09-25 14:42:24 -04:00
# include "i18n.h"
using namespace ARDOUR ;
2006-06-21 19:01:03 -04:00
using namespace PBD ;
2005-09-25 14:42:24 -04:00
using namespace Gtk ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
/**
* Abstract Constructor for base visual time axis classes
*
* @ param name the name / Id of thie TimeAxis
* @ param ed the Ardour PublicEditor
* @ param sess the current session
* @ param canvas the parent canvas object
*/
2009-12-17 13:24:23 -05:00
VisualTimeAxis : : VisualTimeAxis ( const string & name , PublicEditor & ed , ARDOUR : : Session * sess , Canvas & canvas )
2005-09-25 14:42:24 -04:00
: AxisView ( sess ) ,
TimeAxisView ( sess , ed , ( TimeAxisView * ) 0 , canvas ) ,
visual_button ( _ ( " v " ) ) ,
size_button ( _ ( " h " ) )
{
time_axis_name = name ;
_color = unique_random_color ( ) ;
2009-10-14 12:10:01 -04:00
2009-12-11 18:29:48 -05:00
name_entry . signal_activate ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : name_entry_changed ) ) ;
name_entry . signal_button_press_event ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : name_entry_button_press_handler ) ) ;
name_entry . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : name_entry_button_release_handler ) ) ;
name_entry . signal_key_release_event ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : name_entry_key_release_handler ) ) ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
size_button . set_name ( " TrackSizeButton " ) ;
visual_button . set_name ( " TrackVisualButton " ) ;
hide_button . set_name ( " TrackRemoveButton " ) ;
2006-03-15 11:33:00 -05:00
hide_button . add ( * ( Gtk : : manage ( new Gtk : : Image ( get_xpm ( " small_x.xpm " ) ) ) ) ) ;
2009-12-11 18:29:48 -05:00
size_button . signal_button_release_event ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : size_click ) ) ;
visual_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : visual_click ) ) ;
hide_button . signal_clicked ( ) . connect ( sigc : : mem_fun ( * this , & VisualTimeAxis : : hide_click ) ) ;
2010-02-08 19:50:24 -05:00
ARDOUR_UI : : instance ( ) - > set_tip ( size_button , _ ( " Display Height " ) ) ;
ARDOUR_UI : : instance ( ) - > set_tip ( visual_button , _ ( " Visual options " ) ) ;
ARDOUR_UI : : instance ( ) - > set_tip ( hide_button , _ ( " Hide this track " ) ) ;
2009-10-14 12:10:01 -04:00
2005-09-25 16:33:00 -04:00
controls_table . attach ( hide_button , 0 , 1 , 1 , 2 , Gtk : : FILL | Gtk : : EXPAND , Gtk : : FILL | Gtk : : EXPAND ) ;
controls_table . attach ( visual_button , 1 , 2 , 1 , 2 , Gtk : : FILL | Gtk : : EXPAND , Gtk : : FILL | Gtk : : EXPAND ) ;
controls_table . attach ( size_button , 2 , 3 , 1 , 2 , Gtk : : FILL | Gtk : : EXPAND , Gtk : : FILL | Gtk : : EXPAND ) ;
2005-09-25 14:42:24 -04:00
/* remove focus from the buttons */
2005-09-25 16:33:00 -04:00
size_button . unset_flags ( Gtk : : CAN_FOCUS ) ;
hide_button . unset_flags ( Gtk : : CAN_FOCUS ) ;
visual_button . unset_flags ( Gtk : : CAN_FOCUS ) ;
2009-10-14 12:10:01 -04:00
2008-09-10 11:03:30 -04:00
set_height ( hNormal ) ;
2005-09-25 14:42:24 -04:00
}
/**
* VisualTimeAxis Destructor
*
*/
VisualTimeAxis : : ~ VisualTimeAxis ( )
{
}
//---------------------------------------------------------------------------------------//
// Name/Id Accessors/Mutators
void
2005-12-22 07:23:54 -05:00
VisualTimeAxis : : set_time_axis_name ( const string & name , void * src )
2005-09-25 14:42:24 -04:00
{
std : : string old_name = time_axis_name ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
if ( name ! = time_axis_name )
{
time_axis_name = name ;
label_view ( ) ;
editor . route_name_changed ( this ) ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
NameChanged ( time_axis_name , old_name , src ) ; /* EMIT_SIGNAL */
}
}
std : : string
VisualTimeAxis : : name ( ) const
{
return ( time_axis_name ) ;
}
//---------------------------------------------------------------------------------------//
// ui methods & data
/**
* Sets the height of this TrackView to one of the defined TrackHeghts
*
2009-10-14 12:10:01 -04:00
* @ param h
2005-09-25 14:42:24 -04:00
*/
void
2008-09-10 11:03:30 -04:00
VisualTimeAxis : : set_height ( uint32_t h )
2005-09-25 14:42:24 -04:00
{
2008-09-10 11:03:30 -04:00
TimeAxisView : : set_height ( h ) ;
2009-10-14 12:10:01 -04:00
2013-01-11 23:07:29 -05:00
show_name_label ( ) ;
2008-09-10 11:03:30 -04:00
if ( h > = hNormal ) {
other_button_hbox . show_all ( ) ;
} else if ( h > = hSmaller ) {
other_button_hbox . hide_all ( ) ;
} else if ( h > = hSmall ) {
other_button_hbox . hide_all ( ) ;
2005-09-25 14:42:24 -04:00
}
}
/**
* Handle the visuals button click
*
*/
void
VisualTimeAxis : : visual_click ( )
{
popup_display_menu ( 0 ) ;
}
/**
* Handle the hide buttons click
*
*/
void
VisualTimeAxis : : hide_click ( )
{
2006-11-12 22:49:00 -05:00
// LAME fix for hide_button display refresh
hide_button . set_sensitive ( false ) ;
2009-10-14 12:10:01 -04:00
2006-01-09 23:25:47 -05:00
editor . hide_track_in_display ( * this ) ;
2009-10-14 12:10:01 -04:00
2006-11-12 22:49:00 -05:00
hide_button . set_sensitive ( true ) ;
2005-09-25 14:42:24 -04:00
}
/**
* Allows the selection of a new color for this TimeAxis
*
*/
void
VisualTimeAxis : : select_track_color ( )
{
if ( choose_time_axis_color ( ) )
{
//Does nothing at this abstract point
}
}
/**
* Provides a color chooser for the selection of a new time axis color .
*
*/
bool
VisualTimeAxis : : choose_time_axis_color ( )
{
bool picked ;
2005-10-09 01:03:29 -04:00
Gdk : : Color color ;
2005-09-25 14:42:24 -04:00
gdouble current [ 4 ] ;
2005-12-16 17:30:49 -05:00
Gdk : : Color current_color ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
current [ 0 ] = _color . get_red ( ) / 65535.0 ;
current [ 1 ] = _color . get_green ( ) / 65535.0 ;
current [ 2 ] = _color . get_blue ( ) / 65535.0 ;
current [ 3 ] = 1.0 ;
2005-10-09 01:03:29 -04:00
2005-12-16 17:30:49 -05:00
current_color . set_rgb_p ( current [ 0 ] , current [ 1 ] , current [ 2 ] ) ;
2010-04-29 20:16:45 -04:00
color = Gtkmm2ext : : UI : : instance ( ) - > get_color ( _ ( " Color Selection " ) , picked , & current_color ) ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
if ( picked )
{
set_time_axis_color ( color ) ;
}
return ( picked ) ;
}
/**
* Sets the color of this TimeAxis to the specified color c
*
* @ param c the new TimeAxis color
*/
void
2005-10-09 01:03:29 -04:00
VisualTimeAxis : : set_time_axis_color ( Gdk : : Color c )
2005-09-25 14:42:24 -04:00
{
_color = c ;
}
void
2006-07-31 23:23:35 -04:00
VisualTimeAxis : : set_selected_regionviews ( RegionSelection & regions )
2005-09-25 14:42:24 -04:00
{
// Not handled by purely visual TimeAxis
}
//---------------------------------------------------------------------------------------//
// Handle time axis removal
/**
* Handles the Removal of this VisualTimeAxis
*
* @ param src the identity of the object that initiated the change
*/
void
VisualTimeAxis : : remove_this_time_axis ( void * src )
{
vector < string > choices ;
2010-08-16 20:28:20 -04:00
std : : string prompt = string_compose ( _ ( " Do you really want to remove track \" %1 \" ? \n \n You may also lose the playlist used by this track. \n \n (This action cannot be undone, and the session file will be overwritten) " ) , time_axis_name ) ;
2005-09-25 14:42:24 -04:00
choices . push_back ( _ ( " No, do nothing. " ) ) ;
2006-04-20 07:41:45 -04:00
choices . push_back ( _ ( " Yes, remove it. " ) ) ;
2005-09-25 14:42:24 -04:00
2005-09-25 16:33:00 -04:00
Gtkmm2ext : : Choice prompter ( prompt , choices ) ;
2005-09-25 14:42:24 -04:00
2006-04-20 07:41:45 -04:00
if ( prompter . run ( ) = = 1 ) {
2006-03-22 12:03:00 -05:00
/*
defer to idle loop , otherwise we ' ll delete this object
while we ' re still inside this function . . .
*/
2009-12-11 18:29:48 -05:00
Glib : : signal_idle ( ) . connect ( sigc : : bind ( sigc : : ptr_fun ( & VisualTimeAxis : : idle_remove_this_time_axis ) , this , src ) ) ;
2005-09-25 14:42:24 -04:00
}
}
/**
* Callback used to remove this time axis during the gtk idle loop
* This is used to avoid deleting the obejct while inside the remove_this_time_axis
* method
*
* @ param ta the VisualTimeAxis to remove
* @ param src the identity of the object that initiated the change
*/
gint
VisualTimeAxis : : idle_remove_this_time_axis ( VisualTimeAxis * ta , void * src )
{
ta - > VisualTimeAxisRemoved ( ta - > name ( ) , src ) ; /* EMIT_SIGNAL */
delete ta ;
ta = 0 ;
return ( false ) ;
}
//---------------------------------------------------------------------------------------//
// Handle TimeAxis rename
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
/**
* Construct a new prompt to receive a new name for this TimeAxis
*
* @ see finish_time_axis_rename ( )
*/
void
VisualTimeAxis : : start_time_axis_rename ( )
{
2006-01-13 17:46:04 -05:00
ArdourPrompter name_prompter ;
2005-09-25 14:42:24 -04:00
2006-01-13 17:46:04 -05:00
name_prompter . set_prompt ( _ ( " new name: " ) ) ;
2006-04-19 16:42:17 -04:00
name_prompter . add_button ( _ ( " Rename " ) , Gtk : : RESPONSE_ACCEPT ) ;
2006-04-22 11:28:59 -04:00
name_prompter . set_response_sensitive ( Gtk : : RESPONSE_ACCEPT , false ) ;
2006-01-13 17:46:04 -05:00
name_prompter . show_all ( ) ;
2005-09-25 14:42:24 -04:00
2006-01-13 17:46:04 -05:00
switch ( name_prompter . run ( ) ) {
2006-01-13 14:48:55 -05:00
case Gtk : : RESPONSE_ACCEPT :
2005-10-26 21:10:36 -04:00
string result ;
2006-01-13 17:46:04 -05:00
name_prompter . get_result ( result ) ;
if ( result . length ( ) ) {
if ( editor . get_named_time_axis ( result ) ! = 0 ) {
ARDOUR_UI : : instance ( ) - > popup_error ( _ ( " A track already exists with that name " ) ) ;
return ;
}
2009-10-14 12:10:01 -04:00
2006-01-13 17:46:04 -05:00
set_time_axis_name ( result , this ) ;
}
2005-09-25 14:42:24 -04:00
}
label_view ( ) ;
}
/**
2005-10-26 21:10:36 -04:00
* Handles the new name for this TimeAxis from the name prompt
2005-09-25 14:42:24 -04:00
*
2005-10-26 21:10:36 -04:00
* @ see start_time_axis_rename ( )
2005-09-25 14:42:24 -04:00
*/
2005-10-26 21:10:36 -04:00
2005-09-25 14:42:24 -04:00
void
VisualTimeAxis : : label_view ( )
{
2013-01-11 23:07:29 -05:00
name_label . set_text ( time_axis_name ) ;
name_entry . set_text ( time_axis_name ) ;
ARDOUR_UI : : instance ( ) - > set_tip ( name_entry , Glib : : Markup : : escape_text ( time_axis_name ) ) ;
2005-09-25 14:42:24 -04:00
}
//---------------------------------------------------------------------------------------//
2009-10-14 12:10:01 -04:00
// Handle name entry signals
2005-09-25 14:42:24 -04:00
void
VisualTimeAxis : : name_entry_changed ( )
{
2013-01-11 23:07:29 -05:00
TimeAxisView : : name_entry_changed ( ) ;
2005-09-25 14:42:24 -04:00
string x = name_entry . get_text ( ) ;
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
if ( x = = time_axis_name ) {
return ;
}
2006-12-01 01:01:30 -05:00
strip_whitespace_edges ( x ) ;
2005-09-25 14:42:24 -04:00
if ( x . length ( ) = = 0 ) {
name_entry . set_text ( time_axis_name ) ;
return ;
}
if ( ! editor . get_named_time_axis ( x ) ) {
2013-01-11 23:07:29 -05:00
set_time_axis_name ( x , this ) ;
2005-09-25 14:42:24 -04:00
} else {
2006-12-01 01:01:30 -05:00
ARDOUR_UI : : instance ( ) - > popup_error ( _ ( " A track already exists with that name " ) ) ;
2005-09-25 14:42:24 -04:00
name_entry . set_text ( time_axis_name ) ;
}
}
2010-05-31 10:21:43 -04:00
bool
2005-09-25 14:42:24 -04:00
VisualTimeAxis : : name_entry_button_press_handler ( GdkEventButton * ev )
{
if ( ev - > button = = 3 ) {
2010-05-31 10:21:43 -04:00
return true ;
2005-09-25 14:42:24 -04:00
}
2010-05-31 10:21:43 -04:00
return false
2005-09-25 14:42:24 -04:00
}
2010-05-31 10:21:43 -04:00
bool
2005-09-25 14:42:24 -04:00
VisualTimeAxis : : name_entry_button_release_handler ( GdkEventButton * ev )
{
2010-05-31 10:21:43 -04:00
return false ;
2005-09-25 14:42:24 -04:00
}
2010-05-31 10:21:43 -04:00
bool
2005-09-25 14:42:24 -04:00
VisualTimeAxis : : name_entry_key_release_handler ( GdkEventKey * ev )
{
switch ( ev - > keyval ) {
case GDK_Tab :
case GDK_Up :
case GDK_Down :
name_entry_changed ( ) ;
2010-05-31 10:21:43 -04:00
return true ;
2005-09-25 14:42:24 -04:00
default :
2010-05-31 10:21:43 -04:00
break ;
2005-09-25 14:42:24 -04:00
}
2010-05-31 10:21:43 -04:00
return false ;
2005-09-25 14:42:24 -04:00
}
//---------------------------------------------------------------------------------------//
// Super class methods not handled by VisualTimeAxis
2009-10-14 12:10:01 -04:00
2005-09-25 14:42:24 -04:00
void
2012-05-27 16:07:13 -04:00
VisualTimeAxis : : show_timestretch ( framepos_t start , framepos_t end , int layers , int layer )
2005-09-25 14:42:24 -04:00
{
2010-12-03 17:26:29 -05:00
// Not handled by purely visual TimeAxis
2005-09-25 14:42:24 -04:00
}
void
VisualTimeAxis : : hide_timestretch ( )
{
2010-12-03 17:26:29 -05:00
// Not handled by purely visual TimeAxis
2005-09-25 14:42:24 -04:00
}