<menuitem action='ToggleMeasureVisibility'/>
<menuitem action='ToggleWaveformsWhileRecording'/>
<menuitem action='ToggleSummary'/>
+ <menuitem action='ToggleEditGroupTabs'/>
</menu>
<menu name='JACK' action='JACK'>
<menuitem action='JACKDisconnect'/>
#include "bundle_manager.h"
#include "global_port_matrix.h"
#include "editor_drag.h"
+#include "editor_group_tabs.h"
#include "i18n.h"
vertical_adjustment.signal_value_changed().connect (mem_fun(*this, &Editor::tie_vertical_scrolling), true);
track_canvas->signal_map_event().connect (mem_fun (*this, &Editor::track_canvas_map_handler));
- controls_layout.add (edit_controls_vbox);
+ HBox* h = manage (new HBox);
+ _group_tabs = new EditorGroupTabs (this);
+ h->pack_start (*_group_tabs, PACK_SHRINK);
+ h->pack_start (edit_controls_vbox);
+ controls_layout.add (*h);
+
controls_layout.set_name ("EditControlsBase");
controls_layout.add_events (Gdk::SCROLL_MASK);
controls_layout.signal_scroll_event().connect (mem_fun(*this, &Editor::control_layout_scroll), false);
/* re-hide summary widget if necessary */
parameter_changed ("show-summary");
+ parameter_changed ("show-edit-group-tabs");
+
/* now reset all audio_time_axis heights, because widgets might need
to be re-hidden
*/
session->register_with_memento_command_factory(_id, this);
_summary->set_session (session);
+ _group_tabs->set_session (session);
start_updating ();
}
class TimeFXDialog;
class TimeSelection;
class TrackSelection;
+class EditorGroupTabs;
/* <CMT Additions> */
class ImageFrameView;
void toggle_zero_line_visibility ();
void toggle_waveforms_while_recording ();
void set_summary ();
+ void set_edit_group_tabs ();
void toggle_measure_visibility ();
void toggle_logo_visibility ();
void update_canvas_now ();
void streamview_height_changed ();
+ EditorGroupTabs* _group_tabs;
+
friend class Drag;
friend class RegionDrag;
friend class RegionMoveDrag;
friend class RegionInsertDrag;
friend class EditorSummary;
+ friend class EditorGroupTabs;
};
#endif /* __ardour_editor_h__ */
#include "utils.h"
#include "i18n.h"
#include "audio_time_axis.h"
+#include "editor_group_tabs.h"
using namespace Gtk;
using namespace Glib;
ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformsWhileRecording"), _("Show Waveforms While Recording"), mem_fun (*this, &Editor::toggle_waveforms_while_recording));
ActionManager::register_toggle_action (editor_actions, X_("ToggleSummary"), _("Show Summary"), mem_fun (*this, &Editor::set_summary));
+
+ ActionManager::register_toggle_action (editor_actions, X_("ToggleEditGroupTabs"), _("Show Edit Group Tabs"), mem_fun (*this, &Editor::set_edit_group_tabs));
ActionManager::register_toggle_action (editor_actions, X_("ToggleMeasureVisibility"), _("Show Measures"), mem_fun (*this, &Editor::toggle_measure_visibility));
}
}
+void
+Editor::set_edit_group_tabs ()
+{
+ Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleEditGroupTabs"));
+ if (act) {
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+ session->config.set_show_edit_group_tabs (tact->get_active ());
+ }
+}
+
void
Editor::toggle_measure_visibility ()
{
tact->set_active (s);
}
}
+ } else if (p == "show-edit-group-tabs") {
+
+ bool const s = session->config.get_show_edit_group_tabs ();
+ if (s) {
+ _group_tabs->show ();
+ } else {
+ _group_tabs->hide ();
+ }
+
+ Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("ToggleEditGroupTabs"));
+ if (act) {
+ Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
+ if (tact->get_active () != s) {
+ tact->set_active (s);
+ }
+ }
}
}
#include "time_axis_view.h"
#include "prompter.h"
#include "gui_thread.h"
+#include "editor_group_tabs.h"
#include "ardour/route.h"
}
in_edit_group_row_change = false;
+
+ _group_tabs->set_dirty ();
}
void
}
in_edit_group_row_change = false;
+
+ _group_tabs->set_dirty ();
}
void
#include "gui_thread.h"
#include "actions.h"
#include "utils.h"
+#include "editor_group_tabs.h"
#include "pbd/unknown_type.h"
}
_summary->set_dirty ();
+ _group_tabs->set_dirty ();
return false; // do not call again (until needed)
}
EditorSummary::EditorSummary (Editor* e)
: _editor (e),
_session (0),
- _pixmap (0),
- _regions_dirty (true),
- _width (512),
- _height (32),
_x_scale (1),
_y_scale (1),
_last_playhead (-1),
set_dirty ();
}
-/** Destroy */
-EditorSummary::~EditorSummary ()
-{
- if (_pixmap) {
- gdk_pixmap_unref (_pixmap);
- }
-}
-
/** Handle an expose event.
* @param event Event from GTK.
*/
bool
EditorSummary::on_expose_event (GdkEventExpose* event)
{
- /* Render the regions pixmap */
-
- Gdk::Rectangle const exposure (
- event->area.x, event->area.y, event->area.width, event->area.height
- );
-
- Gdk::Rectangle r = exposure;
- Gdk::Rectangle content (0, 0, _width, _height);
- bool intersects;
- r.intersect (content, intersects);
-
- if (intersects) {
-
- GdkPixmap* p = get_pixmap (get_window()->gobj ());
-
- gdk_draw_drawable (
- get_window()->gobj(),
- get_style()->get_fg_gc (Gtk::STATE_NORMAL)->gobj(),
- p,
- r.get_x(),
- r.get_y(),
- r.get_x(),
- r.get_y(),
- r.get_width(),
- r.get_height()
- );
- }
+ CairoWidget::on_expose_event (event);
cairo_t* cr = gdk_cairo_create (get_window()->gobj());
return true;
}
-/** @param drawable GDK drawable.
- * @return pixmap for the regions.
- */
-GdkPixmap *
-EditorSummary::get_pixmap (GdkDrawable* drawable)
-{
- if (_regions_dirty) {
-
- if (_pixmap) {
- gdk_pixmap_unref (_pixmap);
- }
- _pixmap = gdk_pixmap_new (drawable, _width, _height, -1);
-
- cairo_t* cr = gdk_cairo_create (_pixmap);
- render (cr);
- cairo_destroy (cr);
-
- _regions_dirty = false;
- }
-
- return _pixmap;
-}
-
/** Render the required regions to a cairo context.
* @param cr Context.
*/
if (max_height * _y_scale > tallest_region_pixels) {
_y_scale = static_cast<double> (tallest_region_pixels) / max_height;
+
}
/* render regions */
cairo_stroke (cr);
}
-/** Set the summary so that the whole thing will be re-rendered next time it is required */
-void
-EditorSummary::set_dirty ()
-{
- ENSURE_GUI_THREAD (mem_fun (*this, &EditorSummary::set_dirty));
-
- _regions_dirty = true;
- queue_draw ();
-}
-
/** Set the summary so that just the overlays (viewbox, playhead etc.) will be re-rendered */
void
EditorSummary::set_overlays_dirty ()
{
/* Use a dummy, small width and the actual height that we want */
req->width = 64;
- req->height = _height;
+ req->height = 32;
}
-/** Handle a size allocation.
- * @param alloc GTK allocation.
- */
-void
-EditorSummary::on_size_allocate (Gtk::Allocation& alloc)
-{
- Gtk::EventBox::on_size_allocate (alloc);
-
- _width = alloc.get_width ();
- _height = alloc.get_height ();
-
- set_dirty ();
-}
void
EditorSummary::centre_on_click (GdkEventButton* ev)
#ifndef __gtk_ardour_editor_summary_h__
#define __gtk_ardour_editor_summary_h__
-#include <gtkmm/eventbox.h>
+#include "cairo_widget.h"
namespace ARDOUR {
class Session;
/** Class to provide a visual summary of the contents of an editor window; represents
* the whole session as a set of lines, one per region view.
*/
-class EditorSummary : public Gtk::EventBox
+class EditorSummary : public CairoWidget
{
public:
EditorSummary (Editor *);
- ~EditorSummary ();
void set_session (ARDOUR::Session *);
- void set_dirty ();
void set_overlays_dirty ();
private:
- void centre_on_click (GdkEventButton *);
bool on_expose_event (GdkEventExpose *);
void on_size_request (Gtk::Requisition *);
- void on_size_allocate (Gtk::Allocation &);
bool on_button_press_event (GdkEventButton *);
bool on_button_release_event (GdkEventButton *);
bool on_motion_notify_event (GdkEventMotion *);
bool on_scroll_event (GdkEventScroll *);
+ void centre_on_click (GdkEventButton *);
void render (cairo_t *);
- GdkPixmap* get_pixmap (GdkDrawable *);
void render_region (RegionView*, cairo_t*, nframes_t, double) const;
void get_editor (std::pair<double, double> *, std::pair<double, double> *) const;
void set_editor (std::pair<double, double> const &, std::pair<double, double> const &);
Editor* _editor; ///< our editor
ARDOUR::Session* _session; ///< our session
- GdkPixmap* _pixmap; ///< pixmap containing a rendering of the region views, or 0
- bool _regions_dirty; ///< true if _pixmap requires re-rendering, otherwise false
- int _width; ///< pixmap width
- int _height; ///< pixmap height
double _x_scale; ///< pixels per frame for the x axis of the pixmap
double _y_scale;
double _last_playhead;
#include "port_matrix_column_labels.h"
#include "port_matrix.h"
#include "port_matrix_body.h"
+#include "utils.h"
PortMatrixColumnLabels::PortMatrixColumnLabels (PortMatrix* m, PortMatrixBody* b)
: PortMatrixLabels (m, b)
cairo_rectangle (cr, x, _height - rh, w, rh);
}
cairo_fill (cr);
-
- std::pair<std::string, double> const display = display_port_name (cr, (*i)->name, w);
+
+ std::string const upper = Glib::ustring ((*i)->name).uppercase ();
+ std::pair<std::string, double> const display = fit_to_pixels (cr, upper, w);
/* plot it */
set_source_rgb (cr, text_colour());
return std::make_pair (_width, _height);
}
-std::pair<std::string, double>
-PortMatrixComponent::display_port_name (cairo_t* cr, std::string const &n, double avail) const
-{
- /* XXX hopefully there exists a more efficient way of doing this */
-
- Glib::ustring name = Glib::ustring (n).uppercase ();
- bool abbreviated = false;
- uint32_t width = 0;
-
- while (1) {
- if (name.length() <= 2) {
- break;
- }
-
- cairo_text_extents_t ext;
- cairo_text_extents (cr, name.c_str(), &ext);
- if (ext.width < avail) {
- width = ext.width;
- break;
- }
-
- if (abbreviated) {
- name = name.substr (0, name.length() - 2) + ".";
- } else {
- name = name.substr (0, name.length() - 1) + ".";
- abbreviated = true;
- }
- }
-
- return std::make_pair (name, width);
-}
void set_source_rgb (cairo_t *, Gdk::Color const &);
void set_source_rgba (cairo_t *, Gdk::Color const &, double);
- std::pair<std::string, double> display_port_name (cairo_t*, std::string const &, double) const;
/** Render the complete component to a cairo context. */
virtual void render (cairo_t *) = 0;
#include "port_matrix.h"
#include "port_matrix_body.h"
#include "i18n.h"
+#include "utils.h"
PortMatrixRowLabels::PortMatrixRowLabels (PortMatrix* m, PortMatrixBody* b)
: PortMatrixLabels (m, b)
cairo_fill (cr);
/* hence what abbreviation (or not) we need for the group name */
- std::pair<std::string, double> display = display_port_name (cr, (*i)->name, h);
+ std::string const upper = Glib::ustring ((*i)->name).uppercase ();
+ std::pair<std::string, double> display = fit_to_pixels (cr, upper, h);
/* plot it */
set_source_rgb (cr, text_colour());
return txt;
}
+std::pair<std::string, double>
+fit_to_pixels (cairo_t* cr, std::string name, double avail)
+{
+ /* XXX hopefully there exists a more efficient way of doing this */
+
+ bool abbreviated = false;
+ uint32_t width = 0;
+
+ while (1) {
+ if (name.length() <= 4) {
+ break;
+ }
+
+ cairo_text_extents_t ext;
+ cairo_text_extents (cr, name.c_str(), &ext);
+ if (ext.width < avail) {
+ width = ext.width;
+ break;
+ }
+
+ if (abbreviated) {
+ name = name.substr (0, name.length() - 4) + "...";
+ } else {
+ name = name.substr (0, name.length() - 3) + "...";
+ abbreviated = true;
+ }
+ }
+
+ return std::make_pair (name, width);
+}
+
+
gint
just_hide_it (GdkEventAny *ev, Gtk::Window *win)
{
win->hide ();
- return TRUE;
+ return 0;
}
/* xpm2rgb copied from nixieclock, which bore the legend:
}
Glib::ustring fit_to_pixels (const Glib::ustring&, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses = false);
+
+std::pair<std::string, double> fit_to_pixels (cairo_t *, std::string, double);
+
int pixel_width (const Glib::ustring& str, Pango::FontDescription& font);
gint just_hide_it (GdkEventAny*, Gtk::Window*);
automation_time_axis.cc
axis_view.cc
bundle_manager.cc
+ cairo_widget.cc
canvas-flag.cc
canvas-note-event.cc
canvas-note.cc
editor_drag.cc
editor_edit_groups.cc
editor_export_audio.cc
+ editor_group_tabs.cc
editor_hscroller.cc
editor_keyboard.cc
editor_keys.cc
sigc::signal<void> Located;
sigc::signal<void,RouteList&> RouteAdded;
+ sigc::signal<void> RouteEditGroupChanged;
void request_roll_at_and_return (nframes_t start, nframes_t return_to);
void request_bounded_roll (nframes_t start, nframes_t end);
int load_regions (const XMLNode& node);
+ void route_edit_group_changed ();
+
/* SOURCES */
mutable Glib::Mutex source_lock;
CONFIG_VARIABLE (bool, use_video_sync, "use-video-sync", false)
CONFIG_VARIABLE (float, video_pullup, "video-pullup", 0.0f)
CONFIG_VARIABLE (bool, show_summary, "show-summary", true)
+CONFIG_VARIABLE (bool, show_edit_group_tabs, "show-edit-group-tabs", true)
(*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
(*x)->output()->changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
(*x)->processors_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
+ (*x)->edit_group_changed.connect (hide (mem_fun (*this, &Session::route_edit_group_changed)));
if ((*x)->is_master()) {
_master_out = (*x);
(*i)->put_control_outs_at (p);
}
}
+
+void
+Session::route_edit_group_changed ()
+{
+ RouteEditGroupChanged (); /* EMIT SIGNAL */
+}