From b895b677bf29cca95fe0626616d7495113386b04 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 20 Jun 2009 13:41:55 +0000 Subject: Optional tabs down the LHS of the editor window to indicate edit group membership. git-svn-id: svn://localhost/ardour2/branches/3.0@5220 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour.menus.in | 1 + gtk2_ardour/editor.cc | 11 +++- gtk2_ardour/editor.h | 5 ++ gtk2_ardour/editor_actions.cc | 29 +++++++++++ gtk2_ardour/editor_edit_groups.cc | 5 ++ gtk2_ardour/editor_route_list.cc | 2 + gtk2_ardour/editor_summary.cc | 89 ++------------------------------ gtk2_ardour/editor_summary.h | 14 ++--- gtk2_ardour/port_matrix_column_labels.cc | 6 ++- gtk2_ardour/port_matrix_component.cc | 31 ----------- gtk2_ardour/port_matrix_component.h | 1 - gtk2_ardour/port_matrix_row_labels.cc | 4 +- gtk2_ardour/utils.cc | 34 +++++++++++- gtk2_ardour/utils.h | 3 ++ gtk2_ardour/wscript | 2 + 15 files changed, 103 insertions(+), 134 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in index e965f0dee6..b8d34b276a 100644 --- a/gtk2_ardour/ardour.menus.in +++ b/gtk2_ardour/ardour.menus.in @@ -393,6 +393,7 @@ + diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 7f2d502d95..613c91f2b8 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -95,6 +95,7 @@ #include "bundle_manager.h" #include "global_port_matrix.h" #include "editor_drag.h" +#include "editor_group_tabs.h" #include "i18n.h" @@ -452,7 +453,12 @@ Editor::Editor () 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); @@ -974,6 +980,8 @@ Editor::show_window () /* 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 */ @@ -1428,6 +1436,7 @@ Editor::connect_to_session (Session *t) session->register_with_memento_command_factory(_id, this); _summary->set_session (session); + _group_tabs->set_session (session); start_updating (); } diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 81f8eab5aa..66b65e7470 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -114,6 +114,7 @@ class TimeAxisView; class TimeFXDialog; class TimeSelection; class TrackSelection; +class EditorGroupTabs; /* */ class ImageFrameView; @@ -344,6 +345,7 @@ class Editor : public PublicEditor 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 (); @@ -2239,6 +2241,8 @@ public: void update_canvas_now (); void streamview_height_changed (); + EditorGroupTabs* _group_tabs; + friend class Drag; friend class RegionDrag; friend class RegionMoveDrag; @@ -2264,6 +2268,7 @@ public: friend class RegionInsertDrag; friend class EditorSummary; + friend class EditorGroupTabs; }; #endif /* __ardour_editor_h__ */ diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index f3a3fac2e3..99e241862b 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -29,6 +29,7 @@ #include "utils.h" #include "i18n.h" #include "audio_time_axis.h" +#include "editor_group_tabs.h" using namespace Gtk; using namespace Glib; @@ -808,6 +809,8 @@ Editor::register_actions () 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)); @@ -895,6 +898,16 @@ Editor::set_summary () } } +void +Editor::set_edit_group_tabs () +{ + Glib::RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleEditGroupTabs")); + if (act) { + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); + session->config.set_show_edit_group_tabs (tact->get_active ()); + } +} + void Editor::toggle_measure_visibility () { @@ -1289,6 +1302,22 @@ Editor::parameter_changed (std::string p) 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 act = ActionManager::get_action (X_("Editor"), X_("ToggleEditGroupTabs")); + if (act) { + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); + if (tact->get_active () != s) { + tact->set_active (s); + } + } } } diff --git a/gtk2_ardour/editor_edit_groups.cc b/gtk2_ardour/editor_edit_groups.cc index a0e7372ded..9dbdbfad38 100644 --- a/gtk2_ardour/editor_edit_groups.cc +++ b/gtk2_ardour/editor_edit_groups.cc @@ -30,6 +30,7 @@ #include "time_axis_view.h" #include "prompter.h" #include "gui_thread.h" +#include "editor_group_tabs.h" #include "ardour/route.h" @@ -248,6 +249,8 @@ Editor::add_edit_group (RouteGroup* group) } in_edit_group_row_change = false; + + _group_tabs->set_dirty (); } void @@ -288,6 +291,8 @@ Editor::group_flags_changed (void* src, RouteGroup* group) } in_edit_group_row_change = false; + + _group_tabs->set_dirty (); } void diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc index 56cc3f5cf1..1cce9fb517 100644 --- a/gtk2_ardour/editor_route_list.cc +++ b/gtk2_ardour/editor_route_list.cc @@ -33,6 +33,7 @@ #include "gui_thread.h" #include "actions.h" #include "utils.h" +#include "editor_group_tabs.h" #include "pbd/unknown_type.h" @@ -424,6 +425,7 @@ Editor::sync_track_view_list_and_route_list () } _summary->set_dirty (); + _group_tabs->set_dirty (); return false; // do not call again (until needed) } diff --git a/gtk2_ardour/editor_summary.cc b/gtk2_ardour/editor_summary.cc index a56a97e0dd..b7ae937a40 100644 --- a/gtk2_ardour/editor_summary.cc +++ b/gtk2_ardour/editor_summary.cc @@ -37,10 +37,6 @@ using namespace ARDOUR; 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), @@ -70,47 +66,13 @@ EditorSummary::set_session (Session* s) 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()); @@ -148,29 +110,6 @@ EditorSummary::on_expose_event (GdkEventExpose* event) 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. */ @@ -206,6 +145,7 @@ EditorSummary::render (cairo_t* cr) if (max_height * _y_scale > tallest_region_pixels) { _y_scale = static_cast (tallest_region_pixels) / max_height; + } /* render regions */ @@ -247,16 +187,6 @@ EditorSummary::render_region (RegionView* r, cairo_t* cr, nframes_t start, doubl 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 () @@ -273,22 +203,9 @@ EditorSummary::on_size_request (Gtk::Requisition *req) { /* 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) diff --git a/gtk2_ardour/editor_summary.h b/gtk2_ardour/editor_summary.h index 1da6a3985f..1d68e3b793 100644 --- a/gtk2_ardour/editor_summary.h +++ b/gtk2_ardour/editor_summary.h @@ -20,7 +20,7 @@ #ifndef __gtk_ardour_editor_summary_h__ #define __gtk_ardour_editor_summary_h__ -#include +#include "cairo_widget.h" namespace ARDOUR { class Session; @@ -31,28 +31,24 @@ class Editor; /** 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 *, std::pair *) const; void set_editor (std::pair const &, std::pair const &); @@ -60,10 +56,6 @@ private: 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; diff --git a/gtk2_ardour/port_matrix_column_labels.cc b/gtk2_ardour/port_matrix_column_labels.cc index 5c1749c4bc..a1ec392088 100644 --- a/gtk2_ardour/port_matrix_column_labels.cc +++ b/gtk2_ardour/port_matrix_column_labels.cc @@ -23,6 +23,7 @@ #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) @@ -162,8 +163,9 @@ PortMatrixColumnLabels::render (cairo_t* cr) cairo_rectangle (cr, x, _height - rh, w, rh); } cairo_fill (cr); - - std::pair const display = display_port_name (cr, (*i)->name, w); + + std::string const upper = Glib::ustring ((*i)->name).uppercase (); + std::pair const display = fit_to_pixels (cr, upper, w); /* plot it */ set_source_rgb (cr, text_colour()); diff --git a/gtk2_ardour/port_matrix_component.cc b/gtk2_ardour/port_matrix_component.cc index a68e21730d..3086e11e90 100644 --- a/gtk2_ardour/port_matrix_component.cc +++ b/gtk2_ardour/port_matrix_component.cc @@ -110,34 +110,3 @@ PortMatrixComponent::dimensions () return std::make_pair (_width, _height); } -std::pair -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); -} diff --git a/gtk2_ardour/port_matrix_component.h b/gtk2_ardour/port_matrix_component.h index 3980731e55..fcb3c8da8e 100644 --- a/gtk2_ardour/port_matrix_component.h +++ b/gtk2_ardour/port_matrix_component.h @@ -168,7 +168,6 @@ protected: void set_source_rgb (cairo_t *, Gdk::Color const &); void set_source_rgba (cairo_t *, Gdk::Color const &, double); - std::pair display_port_name (cairo_t*, std::string const &, double) const; /** Render the complete component to a cairo context. */ virtual void render (cairo_t *) = 0; diff --git a/gtk2_ardour/port_matrix_row_labels.cc b/gtk2_ardour/port_matrix_row_labels.cc index 8334b7b44f..799fb8c14f 100644 --- a/gtk2_ardour/port_matrix_row_labels.cc +++ b/gtk2_ardour/port_matrix_row_labels.cc @@ -25,6 +25,7 @@ #include "port_matrix.h" #include "port_matrix_body.h" #include "i18n.h" +#include "utils.h" PortMatrixRowLabels::PortMatrixRowLabels (PortMatrix* m, PortMatrixBody* b) : PortMatrixLabels (m, b) @@ -131,7 +132,8 @@ PortMatrixRowLabels::render (cairo_t* cr) cairo_fill (cr); /* hence what abbreviation (or not) we need for the group name */ - std::pair display = display_port_name (cr, (*i)->name, h); + std::string const upper = Glib::ustring ((*i)->name).uppercase (); + std::pair display = fit_to_pixels (cr, upper, h); /* plot it */ set_source_rgb (cr, text_colour()); diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index f5490c025a..dc410136d7 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -113,11 +113,43 @@ fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font return txt; } +std::pair +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: diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h index eb74864a78..cf563560a4 100644 --- a/gtk2_ardour/utils.h +++ b/gtk2_ardour/utils.h @@ -53,6 +53,9 @@ slider_position_to_gain (double pos) } Glib::ustring fit_to_pixels (const Glib::ustring&, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses = false); + +std::pair 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*); diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index a61b3733d2..da2f2edadd 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -81,6 +81,7 @@ def build(bld): automation_time_axis.cc axis_view.cc bundle_manager.cc + cairo_widget.cc canvas-flag.cc canvas-note-event.cc canvas-note.cc @@ -106,6 +107,7 @@ def build(bld): editor_drag.cc editor_edit_groups.cc editor_export_audio.cc + editor_group_tabs.cc editor_hscroller.cc editor_keyboard.cc editor_keys.cc -- cgit v1.2.3