/*
Copyright (C) 2006 Paul Davis
+ Written by Sampo Savolainen
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
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ $Id$
*/
-
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm/stock.h>
#include <gtkmm/label.h>
display_model_composite_all_tracks_rb (_("Composite graph of all tracks"))
{
-
track_list_ready = false;
// Left side: track list + controls
</menu>
<menu action='Autoconnect'>
<menuitem action='AutoConnectNewTrackInputsToHardware'/>
+ <separator/>
<menuitem action='AutoConnectNewTrackOutputsToHardware'/>
- <menuitem action='AutoConnectNewTrackOutputsToHardware'/>
+ <menuitem action='AutoConnectNewTrackOutputsToMaster'/>
<menuitem action='ManuallyConnectNewTrackOutputs'/>
</menu>
<menu action='ControlSurfaces'/>
style "time_axis_view_item_name"
{
- font_name = "sans medium 10"
+ font_name = "sans medium 8"
}
style "default_base" = "medium_text"
act = ActionManager::register_toggle_action (option_actions, X_("UseMIDIcontrol"), _("Use MIDI control"), mem_fun (*this, &ARDOUR_UI::toggle_use_midi_control));
ActionManager::session_sensitive_actions.push_back (act);
- act = ActionManager::register_toggle_action (option_actions, X_("AutoConnectNewTrackInputsToHardware"), _("Connect newtrack inputs to hardware"), mem_fun (*this, &ARDOUR_UI::toggle_AutoConnectNewTrackInputsToHardware));
+ act = ActionManager::register_toggle_action (option_actions, X_("AutoConnectNewTrackInputsToHardware"), _("Connect new track inputs to hardware"), mem_fun (*this, &ARDOUR_UI::toggle_AutoConnectNewTrackInputsToHardware));
ActionManager::session_sensitive_actions.push_back (act);
RadioAction::Group file_header_group;
}
void
-AutomationTimeAxisView::set_height (TrackHeight h)
+AutomationTimeAxisView::set_height (TrackHeight ht)
{
+ uint32_t h = height_to_pixels (ht);
bool changed = (height != (uint32_t) h);
TimeAxisView* state_parent = get_parent_with_state ();
controls_table.show_all ();
- TimeAxisView::set_height (h);
+ TimeAxisView::set_height (ht);
base_rect->property_y2() = h;
for (vector<AutomationLine*>::iterator i = lines.begin(); i != lines.end(); ++i) {
void (Editor::*finished_callback)(ArdourCanvas::Item*, GdkEvent*);
TimeAxisView* last_trackview;
bool x_constrained;
+ bool y_constrained;
bool copy;
bool was_rolling;
bool first_move;
for (pos = 0, i = rows.begin(); i != rows.end(); ++i) {
TimeAxisView *tv = (*i)[route_display_columns.tv];
- if (tv != 0) {
+ if (tv != 0 && !tv->hidden()) {
pos += tv->effective_height;
pos += track_spacing;
}
break;
case MarkerItem:
-
remove_marker (*item, event);
-
break;
case RegionItem:
// if dragging with button2, the motion is x constrained, with Alt-button2 it is y constrained
if (event->button.button == 2) {
- drag_info.x_constrained = true;
+ if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Alt)) {
+ drag_info.y_constrained = true;
+ drag_info.x_constrained = false;
+ } else {
+ drag_info.y_constrained = false;
+ drag_info.x_constrained = true;
+ }
} else {
drag_info.x_constrained = false;
+ drag_info.y_constrained = false;
}
drag_info.grab_frame = event_frame(event, &drag_info.grab_x, &drag_info.grab_y);
drag_info.cumulative_x_drag = cx - drag_info.grab_x ;
drag_info.cumulative_y_drag = cy - drag_info.grab_y ;
- bool x_constrained = false;
-
if (drag_info.x_constrained) {
- if (fabs(drag_info.cumulative_x_drag) < fabs(drag_info.cumulative_y_drag)) {
- cx = drag_info.grab_x;
- x_constrained = true;
-
- } else {
- cy = drag_info.grab_y;
- }
-
- }
+ cx = drag_info.grab_x;
+ }
+ if (drag_info.y_constrained) {
+ cy = drag_info.grab_y;
+ }
cp->line.parent_group().w2i (cx, cy);
cy = min ((double) cp->line.height(), cy);
//translate cx to frames
- jack_nframes_t cx_frames = (jack_nframes_t) floor (cx * frames_per_unit);
+ jack_nframes_t cx_frames = unit_to_frame (cx);
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !x_constrained) {
+ if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier()) && !drag_info.x_constrained) {
snap_to (cx_frames);
}
}
}
+ double x1, x2, y1, y2;
+ track_canvas.get_scroll_region (x1, y1, x2, y2);
+
for (i = all_bbt_points->begin(); i != all_bbt_points->end(); ++i) {
TempoMap::BBTPoint& p = (*i);
line = get_time_line ();
line->property_x1() = xpos;
line->property_x2() = xpos;
- line->property_y2() = 1000;
+ line->property_y2() = y2;
line->property_color_rgba() = color;
line->raise_to_top();
line->show();
/* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
GdkModifierType Keyboard::RelevantModifierKeyMask =
- GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD3_MASK);
+ GdkModifierType (GDK_SHIFT_MASK|GDK_CONTROL_MASK|GDK_MOD1_MASK|GDK_MOD3_MASK);
Keyboard::Keyboard ()
}
if (no_splash) {
- cerr << _("Copyright (C) 1999-2005 Paul Davis") << endl
+ cerr << _("Copyright (C) 1999-2006 Paul Davis") << endl
<< _("Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker") << endl
<< endl
<< _("Ardour comes with ABSOLUTELY NO WARRANTY") << endl
str = region.name();
}
+ if (region.speed_mismatch (trackview.session().frame_rate())) {
+ str = string ("*") + str;
+ }
+
if (region.muted()) {
str = string ("!") + str;
}
- set_item_name (region.name(), this);
+ set_item_name (str, this);
set_name_text (str);
}
#include <ardour/types.h>
#include <ardour/ardour.h>
+#include <gtkmm2ext/utils.h>
+
#include "public_editor.h"
#include "time_axis_view_item.h"
#include "time_axis_view.h"
using namespace Glib;
//------------------------------------------------------------------------------
-/** Initialize static memeber data */
+/** Initialize const static memeber data */
+
Pango::FontDescription TimeAxisViewItem::NAME_FONT;
bool TimeAxisViewItem::have_name_font = false;
const double TimeAxisViewItem::NAME_X_OFFSET = 15.0;
-const double TimeAxisViewItem::NAME_Y_OFFSET = 15.0 ; /* XXX depends a lot on the font size, sigh. */
-const double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE = 15.0 ; /* ditto */
-const double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH = 32.0 ; /* ditto */
const double TimeAxisViewItem::GRAB_HANDLE_LENGTH = 6 ;
+double TimeAxisViewItem::NAME_Y_OFFSET;
+double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
+double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
+
//---------------------------------------------------------------------------------------//
// Constructor / Desctructor
: trackview (tv)
{
if (!have_name_font) {
+
+ /* first constructed item sets up font info */
+
NAME_FONT = get_font_for_style (N_("TimeAxisViewItemName"));
+
+ Gtk::Window win;
+ Gtk::Label foo;
+ win.add (foo);
+
+ Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
+ int width;
+ int height;
+
+ layout->set_font_description (NAME_FONT);
+ Gtkmm2ext::get_ink_pixel_size (layout, width, height);
+
+ NAME_Y_OFFSET = height + 4;
+ NAME_HIGHLIGHT_SIZE = height + 6;
+ NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2;
+
have_name_font = true;
}
if (visibility & ShowNameText) {
name_text = new ArdourCanvas::Text (*group);
name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
- name_text->property_y() = (double) trackview.height + 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
+ /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
+ then NAME_Y_OFFSET to position the text in the vertical center of the highlight
+ */
+ name_text->property_y() = (double) trackview.height - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
name_text->property_font_desc() = NAME_FONT;
name_text->property_anchor() = Gtk::ANCHOR_NW;
}
int width;
+
ustring ustr = fit_to_pixels (item_name, (int) floor (pixel_width - NAME_X_OFFSET), NAME_FONT, width);
if (ustr.empty()) {
gint
TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
{
- item->ItemRemoved(item->get_item_name(), src) ; /* EMIT_SIGNAL */
- delete item ;
- item = 0 ;
- return(false) ;
+ item->ItemRemoved (item->get_item_name(), src) ; /* EMIT_SIGNAL */
+ delete item;
+ item = 0;
+ return false;
}
static Pango::FontDescription NAME_FONT ;
static bool have_name_font;
static const double NAME_X_OFFSET ;
- static const double NAME_Y_OFFSET ;
- static const double NAME_HIGHLIGHT_SIZE ;
- static const double NAME_HIGHLIGHT_THRESH ;
static const double GRAB_HANDLE_LENGTH ;
+ /* these are not constant, but vary with the pixel size
+ of the font used to display the item name.
+ */
+ static double NAME_Y_OFFSET ;
+ static double NAME_HIGHLIGHT_SIZE ;
+ static double NAME_HIGHLIGHT_THRESH ;
/**
* Handles the Removal of this time axis item
bool equivalent (const AudioRegion&);
bool size_equivalent (const AudioRegion&);
+ bool speed_mismatch (float) const;
+
void lock_sources ();
void unlock_sources ();
Source& source (uint32_t n=0) const { if (n < sources.size()) return *sources[n]; else return *sources[0]; }
~CoreAudioSource ();
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
+ float sample_rate() const;
private:
ExtAudioFileRef af;
void mark_for_remove();
string peak_path(string audio_path);
string path() const { return _path; }
+ float sample_rate () const;
virtual int seek (jack_nframes_t frame) {return 0; }
virtual jack_nframes_t last_capture_start_frame() const { return 0; }
};
struct ChunkInfo {
- string name;
- uint32_t size;
- off64_t offset;
+ std::string name;
+ uint32_t size;
+ off64_t offset;
ChunkInfo (string s, uint32_t sz, off64_t o)
: name (s), size (sz), offset (o) {}
SndFileSource (const XMLNode&);
~SndFileSource ();
- jack_nframes_t length() const { return _info.frames; }
-
+ jack_nframes_t length() const { return _info.frames; }
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
+ float sample_rate () const;
private:
SNDFILE *sf;
return 0;
}
+ virtual float sample_rate () const { return 0; }
+
uint32_t use_cnt() const { return _use_cnt; }
void use ();
void release ();
}
}
+bool
+AudioRegion::speed_mismatch (float sr) const
+{
+ if (sources.empty()) {
+ /* impossible, but ... */
+ return false;
+ }
+
+ float fsr = sources.front()->sample_rate();
+
+ return fsr == sr;
+}
+
extern "C" {
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t cnt, intptr_t data, uint32_t n_chan, double samples_per_unit)
return real_cnt;
}
+float
+CoreAudioSource::sample_rate() const
+{
+ /* XXX taybin fill me in please */
+
+ return 44100.0f;
+}
_path, header.data.size, _length * sizeof (Sample)) << endmsg;
}
- if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
- warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
- _path, header.format.nSamplesPerSec, rate) << endmsg;
- }
+// if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
+// warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
+// _path, header.format.nSamplesPerSec, rate) << endmsg;
+// }
return 0;
}
+float
+FileSource::sample_rate () const
+{
+ return header.format.nSamplesPerSec;
+}
+
int
FileSource::write_header()
{
}
}
+float
+SndFileSource::sample_rate () const
+{
+ return _info.samplerate;
+}
+
jack_nframes_t
SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{