X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ftime_axis_view_item.cc;h=0e66ab2bae2b1372344f565c1572471e7a97df30;hb=cd9fdb935f08966cc8c7170a39870e8adcae69d8;hp=abab306a84d548044c3ea11b58c746895e42aa93;hpb=fe13d08874f08b723df53116e5655c3d229a657e;p=ardour.git diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index abab306a84..0e66ab2bae 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -15,10 +15,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include +#include #include #include @@ -68,7 +68,7 @@ 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, - jack_nframes_t start, jack_nframes_t duration, + nframes_t start, nframes_t duration, Visibility vis) : trackview (tv) { @@ -89,32 +89,62 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& layout->set_font_description (NAME_FONT); Gtkmm2ext::get_ink_pixel_size (layout, width, height); - NAME_Y_OFFSET = height + 4; + NAME_Y_OFFSET = height + 6; NAME_HIGHLIGHT_SIZE = height + 6; NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2; have_name_font = true; } + group = new ArdourCanvas::Group (parent); + + init (it_name, spu, base_color, start, duration, vis); + +} + +TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other) + : trackview (other.trackview) +{ + + Gdk::Color c; + int r,g,b,a; + + UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a); + c.set_rgb_p (r/255.0, g/255.0, b/255.0); + + /* share the other's parent, but still create a new group */ + + Gnome::Canvas::Group* parent = other.group->property_parent(); + + group = new ArdourCanvas::Group (*parent); + + init (other.item_name, other.samples_per_unit, c, other.frame_position, other.item_duration, other.visibility); +} + + +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 ; item_duration = duration ; name_connected = false; - fill_opacity = 50; + fill_opacity = 60; position_locked = false ; max_item_duration = ARDOUR::max_frames; min_item_duration = 0 ; show_vestigial = true; visibility = vis; + _sensitive = true; if (duration == 0) { warning << "Time Axis Item Duration == 0" << endl ; } - group = new ArdourCanvas::Group (parent); - vestigial_frame = new ArdourCanvas::SimpleRect (*group); vestigial_frame->property_x1() = (double) 0.0; vestigial_frame->property_y1() = (double) 1.0; @@ -137,8 +167,12 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& uint32_t outline_what = 0x1|0x2|0x4|0x8; - if (visibility & HideFrameLR) { - outline_what &= ~(0x1 | 0x2); + if (visibility & HideFrameLeft) { + outline_what &= ~(0x1); + } + + if (visibility & HideFrameRight) { + outline_what &= ~(0x2); } if (visibility & HideFrameTB) { @@ -217,7 +251,6 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& set_position (start, this) ; } - /** * Destructor */ @@ -238,7 +271,7 @@ TimeAxisViewItem::~TimeAxisViewItem() * @return true if the position change was a success, false otherwise */ bool -TimeAxisViewItem::set_position(jack_nframes_t pos, void* src, double* delta) +TimeAxisViewItem::set_position(nframes_t pos, void* src, double* delta) { if (position_locked) { return false; @@ -278,7 +311,7 @@ TimeAxisViewItem::set_position(jack_nframes_t pos, void* src, double* delta) * * @return the position of this item */ -jack_nframes_t +nframes_t TimeAxisViewItem::get_position() const { return frame_position; @@ -292,7 +325,7 @@ TimeAxisViewItem::get_position() const * @return true if the duration change was succesful, false otherwise */ bool -TimeAxisViewItem::set_duration (jack_nframes_t dur, void* src) +TimeAxisViewItem::set_duration (nframes_t dur, void* src) { if ((dur > max_item_duration) || (dur < min_item_duration)) { warning << string_compose (_("new duration %1 frames is out of bounds for %2"), get_item_name(), dur) @@ -306,9 +339,7 @@ TimeAxisViewItem::set_duration (jack_nframes_t dur, void* src) item_duration = dur; - double pixel_width = trackview.editor.frame_to_pixel (dur); - - reset_width_dependent_items (pixel_width); + reset_width_dependent_items (trackview.editor.frame_to_pixel (dur)); DurationChanged (dur, src) ; /* EMIT_SIGNAL */ return true; @@ -318,7 +349,7 @@ TimeAxisViewItem::set_duration (jack_nframes_t dur, void* src) * Returns the duration of this item * */ -jack_nframes_t +nframes_t TimeAxisViewItem::get_duration() const { return (item_duration); @@ -331,7 +362,7 @@ TimeAxisViewItem::get_duration() const * @param src the identity of the object that initiated the change */ void -TimeAxisViewItem::set_max_duration(jack_nframes_t dur, void* src) +TimeAxisViewItem::set_max_duration(nframes_t dur, void* src) { max_item_duration = dur ; MaxDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */ @@ -342,7 +373,7 @@ TimeAxisViewItem::set_max_duration(jack_nframes_t dur, void* src) * * @return the maximum duration that this item may be set to */ -jack_nframes_t +nframes_t TimeAxisViewItem::get_max_duration() const { return (max_item_duration) ; @@ -355,7 +386,7 @@ TimeAxisViewItem::get_max_duration() const * @param src the identity of the object that initiated the change */ void -TimeAxisViewItem::set_min_duration(jack_nframes_t dur, void* src) +TimeAxisViewItem::set_min_duration(nframes_t dur, void* src) { min_item_duration = dur ; MinDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */ @@ -366,7 +397,7 @@ TimeAxisViewItem::set_min_duration(jack_nframes_t dur, void* src) * * @return the nimum duration that this item mey be set to */ -jack_nframes_t +nframes_t TimeAxisViewItem::get_min_duration() const { return(min_item_duration) ; @@ -460,6 +491,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 */ } } @@ -525,23 +557,26 @@ 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 (); } } /** - * Set the height of this item + * Set the y position and height of this item. * + * @param y the new y position * @param h the new height */ void -TimeAxisViewItem::set_height(double height) +TimeAxisViewItem::set_y_position_and_height (double y, double h) { if (name_highlight) { - if (height < NAME_HIGHLIGHT_THRESH) { + if (h < NAME_HIGHLIGHT_THRESH) { name_highlight->hide(); if (name_text) { name_text->hide(); @@ -553,20 +588,20 @@ TimeAxisViewItem::set_height(double height) } } - if (height > NAME_HIGHLIGHT_SIZE) { - name_highlight->property_y1() = (double) height+1 - NAME_HIGHLIGHT_SIZE; - name_highlight->property_y2() = (double) height; + if (h > NAME_HIGHLIGHT_SIZE) { + name_highlight->property_y1() = (double) y + h + 1 - NAME_HIGHLIGHT_SIZE; + name_highlight->property_y2() = (double) y + h; } else { /* it gets hidden now anyway */ - name_highlight->property_y1() = (double) 1.0; - name_highlight->property_y2() = (double) height; + name_highlight->property_y1() = (double) y; + name_highlight->property_y2() = (double) y + h; } } if (name_text) { - name_text->property_y() = height+1 - NAME_Y_OFFSET; - if (height < NAME_HIGHLIGHT_THRESH) { + name_text->property_y() = y + h + 1 - NAME_Y_OFFSET; + if (h < NAME_HIGHLIGHT_THRESH) { name_text->property_fill_color_rgba() = fill_color; } else { @@ -575,10 +610,12 @@ TimeAxisViewItem::set_height(double height) } if (frame) { - frame->property_y2() = height+1; + frame->property_y1() = y; + frame->property_y2() = y + h + 1; } - vestigial_frame->property_y2() = height+1; + vestigial_frame->property_y1() = y; + vestigial_frame->property_y2() = y + h + 1; } /** @@ -847,7 +884,7 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) } } else { name_highlight->show(); - if (name_text) { + if (name_text && !get_item_name().empty()) { name_text->show(); reset_name_width (pixel_width); } @@ -885,34 +922,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; + }