X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=gtk2_ardour%2Ftime_axis_view_item.cc;h=1e75a7845ea5f1d6d4c60a76844c052dc36b1754;hb=c892bc35c8048514a07499871a23eb94cbd101c0;hp=09d959358dd0d79a3a5474bd19c376c99d3d89d8;hpb=edfc81352e66a412c6bc180c15f788512eccbe42;p=ardour.git diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index 09d959358d..1e75a7845e 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -17,10 +17,11 @@ */ -#include +#include "pbd/error.h" +#include "pbd/stacktrace.h" -#include -#include +#include "ardour/types.h" +#include "ardour/ardour.h" #include @@ -31,6 +32,7 @@ #include "utils.h" #include "canvas_impl.h" #include "rgb_macros.h" +#include "ardour_ui.h" #include "i18n.h" @@ -38,11 +40,12 @@ using namespace std; using namespace Editing; using namespace Glib; using namespace PBD; +using namespace ARDOUR; //------------------------------------------------------------------------------ /** Initialize const static memeber data */ -Pango::FontDescription TimeAxisViewItem::NAME_FONT; +Pango::FontDescription* TimeAxisViewItem::NAME_FONT = 0; bool TimeAxisViewItem::have_name_font = false; const double TimeAxisViewItem::NAME_X_OFFSET = 15.0; const double TimeAxisViewItem::GRAB_HANDLE_LENGTH = 6 ; @@ -67,9 +70,9 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH; * @param duration the duration of this item */ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color, - nframes_t start, nframes_t duration, + nframes_t start, nframes_t duration, bool recording, Visibility vis) - : trackview (tv) + : trackview (tv), _recregion(recording) { if (!have_name_font) { @@ -85,10 +88,10 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& int width; int height; - layout->set_font_description (NAME_FONT); + layout->set_font_description (*NAME_FONT); Gtkmm2ext::get_ink_pixel_size (layout, width, height); - NAME_Y_OFFSET = height + 6; + NAME_Y_OFFSET = height + 5; NAME_HIGHLIGHT_SIZE = height + 6; NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2; @@ -102,7 +105,8 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& } TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other) - : trackview (other.trackview) + : sigc::trackable(other) + , trackview (other.trackview) { Gdk::Color c; @@ -125,6 +129,8 @@ void TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, Visibility vis) { item_name = it_name ; + name_text_width = ::pixel_width (it_name, *NAME_FONT); + last_name_text_width = 0; samples_per_unit = spu ; should_show_selection = true; frame_position = start ; @@ -145,20 +151,22 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo vestigial_frame = new ArdourCanvas::SimpleRect (*group); vestigial_frame->property_x1() = (double) 0.0; vestigial_frame->property_y1() = (double) 1.0; - vestigial_frame->property_x2() = 2.0; - vestigial_frame->property_y2() = (double) trackview.height; - vestigial_frame->property_outline_color_rgba() = color_map[cVestigialFrameOutline]; - vestigial_frame->property_fill_color_rgba() = color_map[cVestigialFrameFill]; + vestigial_frame->property_x2() = (double) 2.0; + vestigial_frame->property_y2() = (double) trackview.current_height(); + vestigial_frame->property_outline_what() = 0xF; + vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get(); + vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get(); vestigial_frame->hide (); if (visibility & ShowFrame) { frame = new ArdourCanvas::SimpleRect (*group); frame->property_x1() = (double) 0.0; frame->property_y1() = (double) 1.0; - frame->property_x2() = (double) trackview.editor.frame_to_pixel(duration); - frame->property_y2() = (double) trackview.height; - frame->property_outline_color_rgba() = color_map[cTimeAxisFrameOutline]; - frame->property_fill_color_rgba() = color_map[cTimeAxisFrameFill]; + frame->property_x2() = (double) trackview.editor().frame_to_pixel(duration); + frame->property_y2() = (double) trackview.current_height(); + frame->property_outline_pixels() = 1; + frame->property_outline_what() = 0xF; + frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get(); /* by default draw all 4 edges */ @@ -186,15 +194,13 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo name_highlight = new ArdourCanvas::SimpleRect (*group); if (visibility & FullWidthNameHighlight) { name_highlight->property_x1() = (double) 0.0; - name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration)); + name_highlight->property_x2() = (double) (trackview.editor().frame_to_pixel(item_duration)); } else { name_highlight->property_x1() = (double) 1.0; - name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration)) - 1; + name_highlight->property_x2() = (double) (trackview.editor().frame_to_pixel(item_duration)) - 1; } - name_highlight->property_y1() = (double) (trackview.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE); - name_highlight->property_y2() = (double) (trackview.height - 1); - name_highlight->property_outline_color_rgba() = color_map[cNameHighlightFill]; - name_highlight->property_fill_color_rgba() = color_map[cNameHighlightOutline]; + name_highlight->property_y1() = (double) (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE); + name_highlight->property_y2() = (double) (trackview.current_height() - 1); name_highlight->set_data ("timeaxisviewitem", this); @@ -205,11 +211,11 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo if (visibility & ShowNameText) { name_text = new ArdourCanvas::Text (*group); name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET; - /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight, + /* trackview.current_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_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET; + name_text->property_font_desc() = *NAME_FONT; name_text->property_anchor() = Gtk::ANCHOR_NW; name_text->set_data ("timeaxisviewitem", this); @@ -226,16 +232,14 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo frame_handle_start->property_x2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH; frame_handle_start->property_y1() = (double) 1.0; frame_handle_start->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH+1; - frame_handle_start->property_outline_color_rgba() = color_map[cFrameHandleStartOutline]; - frame_handle_start->property_fill_color_rgba() = color_map[cFrameHandleStartFill]; - + frame_handle_start->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get(); + frame_handle_end = new ArdourCanvas::SimpleRect (*group); - frame_handle_end->property_x1() = (double) (trackview.editor.frame_to_pixel(get_duration())) - (TimeAxisViewItem::GRAB_HANDLE_LENGTH); - frame_handle_end->property_x2() = (double) trackview.editor.frame_to_pixel(get_duration()); + frame_handle_end->property_x1() = (double) (trackview.editor().frame_to_pixel(get_duration())) - (TimeAxisViewItem::GRAB_HANDLE_LENGTH); + frame_handle_end->property_x2() = (double) trackview.editor().frame_to_pixel(get_duration()); frame_handle_end->property_y1() = (double) 1; frame_handle_end->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH + 1; - frame_handle_end->property_outline_color_rgba() = color_map[cFrameHandleEndOutline]; - frame_handle_end->property_fill_color_rgba() = color_map[cFrameHandleEndFill]; + frame_handle_end->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get(); } else { frame_handle_start = 0; @@ -336,7 +340,7 @@ TimeAxisViewItem::set_duration (nframes_t dur, void* src) item_duration = dur; - reset_width_dependent_items (trackview.editor.frame_to_pixel (dur)); + reset_width_dependent_items (trackview.editor().frame_to_pixel (dur)); DurationChanged (dur, src) ; /* EMIT_SIGNAL */ return true; @@ -488,6 +492,7 @@ TimeAxisViewItem::set_item_name(std::string new_name, void* src) if (new_name != item_name) { std::string temp_name = item_name ; item_name = new_name ; + name_text_width = ::pixel_width (new_name, *NAME_FONT); NameChanged (item_name, temp_name, src) ; /* EMIT_SIGNAL */ } } @@ -553,10 +558,12 @@ TimeAxisViewItem::get_time_axis_view() * @param new_name the new name text to display */ void -TimeAxisViewItem::set_name_text(std::string new_name) +TimeAxisViewItem::set_name_text(const ustring& new_name) { if (name_text) { - name_text->property_text() = new_name.c_str(); + name_text->property_text() = new_name; + name_text_width = pixel_width (new_name, *NAME_FONT); + name_text_size_cache.clear (); } } @@ -566,7 +573,7 @@ TimeAxisViewItem::set_name_text(std::string new_name) * @param h the new height */ void -TimeAxisViewItem::set_height(double height) +TimeAxisViewItem::set_height (double height) { if (name_highlight) { if (height < NAME_HIGHLIGHT_THRESH) { @@ -631,7 +638,7 @@ TimeAxisViewItem::get_canvas_frame() /** * */ -ArdourCanvas::Item* +ArdourCanvas::Group* TimeAxisViewItem::get_canvas_group() { return (group) ; @@ -672,7 +679,7 @@ TimeAxisViewItem::compute_colors(Gdk::Color& base_color) r = base_color.get_red()/256 ; g = base_color.get_green()/256 ; b = base_color.get_blue()/256 ; - fill_color = RGBA_TO_UINT(r,g,b,255) ; + fill_color = RGBA_TO_UINT(r,g,b,160) ; /* for minor colors: if the overall saturation is strong, make the minor colors light. @@ -788,11 +795,16 @@ TimeAxisViewItem::set_frame_color() uint32_t r,g,b,a; if (_selected && should_show_selection) { - UINT_TO_RGBA(color_map[cSelectedFrameBase], &r, &g, &b, &a); - frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity); + UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a); + frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a); } else { - UINT_TO_RGBA(color_map[cFrameBase], &r, &g, &b, &a); - frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity); + if (_recregion) { + UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a); + frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a); + } else { + UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a); + frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a); + } } } } @@ -806,11 +818,11 @@ TimeAxisViewItem::set_trim_handle_colors() { if (frame_handle_start) { if (position_locked) { - frame_handle_start->property_fill_color_rgba() = color_map[cTrimHandleLockedStart]; - frame_handle_end->property_fill_color_rgba() = color_map[cTrimHandleLockedEnd]; + frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get(); + frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get(); } else { - frame_handle_start->property_fill_color_rgba() = color_map[cTrimHandleStart]; - frame_handle_end->property_fill_color_rgba() = color_map[cTrimHandleEnd]; + frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get(); + frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get(); } } } @@ -913,34 +925,87 @@ TimeAxisViewItem::reset_name_width (double pixel_width) if (name_text == 0) { return; } - - int width; - - ustring ustr = fit_to_pixels (item_name, (int) floor (pixel_width - NAME_X_OFFSET), NAME_FONT, width); - if (ustr.empty()) { - - name_text->hide (); - - } else { - - /* don't use name for event handling if it leaves no room - for trimming to work. - */ + int limit = (int) floor (pixel_width - NAME_X_OFFSET); + bool shrinking = (last_name_text_width > pixel_width); + int actual_width; + ustring ustr; + ustring::size_type n; + + if ((last_name_text_width && // we did this once + shrinking && // we're getting smaller + (name_text_width <= limit) && // fits the new size + (name_text_width <= last_name_text_width - NAME_X_OFFSET))) { // fit into the old size too + last_name_text_width = pixel_width; + return; + } + + /* now check the cache of existing truncations */ + + Gtk::Label foo; + Glib::RefPtr layout = foo.create_pango_layout (""); + + for (n = item_name.length(); n > 0; --n) { - if (pixel_width - width < (NAME_X_OFFSET * 2.0)) { - if (name_connected) { - name_connected = false; + map::iterator i; + + if ((i = name_text_size_cache.find (n)) != name_text_size_cache.end()) { + + /* we know the length of this substring already */ + + if ((actual_width = (*i).second) < limit) { + + /* it fits, use it */ + + ustr = item_name.substr (0, n); + break; } + } else { - if (!name_connected) { - name_connected = true; + + /* we don't know the length of this substring already, so compute + it and put it into the cache. + */ + + layout->set_text (item_name.substr (0, n)); + + int width, height; + Gtkmm2ext::get_ink_pixel_size (layout, width, height); + + name_text_size_cache[n] = width; + + if ((actual_width = width) < limit) { + ustr = item_name.substr (0, n); + break; } } - - name_text->property_text() = ustr; - name_text->show(); } + + if (n == 0) { + name_text->property_text() = ""; + last_name_text_width = pixel_width; + return; + } + + /* don't use name for event handling if it leaves no room + for trimming to work. + */ + + if (pixel_width - actual_width < (NAME_X_OFFSET * 2.0)) { + if (name_connected) { + name_connected = false; + } + } else { + if (!name_connected) { + name_connected = true; + } + } + + name_text->property_text() = ustr; + name_text_width = actual_width; + name_text->show(); + last_name_text_width = pixel_width; + } @@ -983,3 +1048,15 @@ TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src) item = 0; return false; } + +void +TimeAxisViewItem::set_y (double y) +{ + double const old = group->property_y (); + if (y != old) { + group->move (0, y - old); + } +} + + +