From 2641231cb2125a0188264e833c6e6e77202910a9 Mon Sep 17 00:00:00 2001 From: Nick Mainsbridge Date: Tue, 2 Jun 2009 17:45:18 +0000 Subject: Fix memory leak in name text pixbuf generation, move RegionView::_height to TimeAxisViewItem, clean up name_highlight vs name_text code (removes assumpton that one implied the other), fix mouse offset when track resizing past the smallest size, reinstate zooming to 1 frame per pixel. git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5117 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/audio_region_view.cc | 7 --- gtk2_ardour/editor.cc | 6 +- gtk2_ardour/editor_ops.cc | 4 +- gtk2_ardour/marker.cc | 38 ++---------- gtk2_ardour/region_view.cc | 5 -- gtk2_ardour/region_view.h | 1 - gtk2_ardour/time_axis_view.cc | 14 +++-- gtk2_ardour/time_axis_view.h | 1 + gtk2_ardour/time_axis_view_item.cc | 123 ++++++++++++++++++++----------------- gtk2_ardour/time_axis_view_item.h | 10 ++- gtk2_ardour/utils.cc | 27 ++++++++ gtk2_ardour/utils.h | 4 ++ 12 files changed, 128 insertions(+), 112 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 290d8b382c..705a870da0 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -432,9 +432,6 @@ AudioRegionView::set_height (gdouble height) height -= 2; TimeAxisViewItem::set_height (height); - - _height = height; - for (uint32_t n=0; n < wcnt; ++n) { gdouble ht; @@ -464,10 +461,6 @@ AudioRegionView::set_height (gdouble height) manage_zero_line (); reset_fade_shapes (); - if (name_pixbuf) { - name_pixbuf->raise_to_top(); - } - } void diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 8c846b60c2..0865854cf9 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -4430,8 +4430,8 @@ Editor::set_frames_per_unit (double fpu) return; } - if (fpu < 2.0) { - fpu = 2.0; + if (fpu < 1.0) { + fpu = 1.0; } @@ -5055,7 +5055,7 @@ Editor::idle_resize () (*i)->idle_resize (resize_idle_target); } pending_resizes.clear(); - flush_canvas (); + //flush_canvas (); resize_idle_id = -1; return false; } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index fb331eafc5..40e1b22aed 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -1615,7 +1615,7 @@ Editor::temporal_zoom (gdouble fpu) /* XXX this limit is also in ::set_frames_per_unit() */ - if (frames_per_unit <= 2.0 && fpu <= frames_per_unit) { + if (frames_per_unit < 1.0 && fpu <= frames_per_unit) { return; } @@ -2583,8 +2583,8 @@ Editor::rename_region() d.get_vbox()->set_border_width (12); d.get_vbox()->pack_start (hbox, false, false); - d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); d.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); d.set_size_request (300, -1); d.set_position (Gtk::WIN_POS_MOUSE); diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 6d00052430..a2ed97b516 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -244,20 +244,17 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con /* setup name pixbuf sizes */ name_font = get_font_for_style (N_("MarkerText")); - Gtk::Window win; Gtk::Label foo; - win.add (foo); - Glib::RefPtr 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_height = height + 6; + Gtkmm2ext::get_ink_pixel_size (layout, width, name_height); name_pixbuf = new ArdourCanvas::Pixbuf(*group); name_pixbuf->property_x() = label_offset; + name_pixbuf->property_y() = (13 / 2) - (name_height / 2); set_name (annotation.c_str()); @@ -349,35 +346,12 @@ Marker::the_item() const void Marker::set_name (const string& new_name) { - uint32_t pb_width; - double font_size; - - font_size = name_font->get_size() / Pango::SCALE; - pb_width = new_name.length() * font_size; - - Glib::RefPtr buf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, pb_width, name_height); - - cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, pb_width, name_height); - cairo_t *cr = cairo_create (surface); - cairo_text_extents_t te; - cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); - cairo_select_font_face (cr, name_font->get_family().c_str(), - CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size (cr, font_size); - cairo_text_extents (cr, new_name.c_str(), &te); - - cairo_move_to (cr, 0.5, - 0.5 - te.height / 2 - te.y_bearing + name_height / 2); - cairo_show_text (cr, new_name.c_str()); - - unsigned char* src = cairo_image_surface_get_data (surface); - convert_bgra_to_rgba(src, buf->get_pixels(), pb_width, name_height); - - cairo_destroy(cr); - name_pixbuf->property_pixbuf() = buf; + int name_width = pixel_width (new_name, *name_font) + 2; + + name_pixbuf->property_pixbuf() = pixbuf_from_ustring(new_name, name_font, name_width, name_height); if (_type == End || _type == LoopEnd || _type == PunchOut) { - name_pixbuf->property_x() = -(te.width); + name_pixbuf->property_x() = - (name_width); } } diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index 2bbfa4b5f5..47d0c38ef9 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -75,7 +75,6 @@ RegionView::RegionView (ArdourCanvas::Group* parent, , current_visible_sync_position(0.0) , valid(false) , _pixel_width(1.0) - , _height(1.0) , in_destructor(false) , wait_for_data(false) { @@ -90,7 +89,6 @@ RegionView::RegionView (const RegionView& other) current_visible_sync_position = other.current_visible_sync_position; valid = false; _pixel_width = other._pixel_width; - _height = other._height; } RegionView::RegionView (const RegionView& other, boost::shared_ptr other_region) @@ -106,7 +104,6 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr other current_visible_sync_position = other.current_visible_sync_position; valid = false; _pixel_width = other._pixel_width; - _height = other._height; } RegionView::RegionView (ArdourCanvas::Group* parent, @@ -124,7 +121,6 @@ RegionView::RegionView (ArdourCanvas::Group* parent, , current_visible_sync_position(0.0) , valid(false) , _pixel_width(1.0) - , _height(1.0) , in_destructor(false) , wait_for_data(false) { @@ -136,7 +132,6 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) editor = 0; valid = true; in_destructor = false; - _height = 0; wait_for_data = wfd; sync_mark = 0; sync_line = 0; diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 6562e8c3f0..5ae1f96fb0 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -133,7 +133,6 @@ class RegionView : public TimeAxisViewItem bool valid; ///< see StreamView::redisplay_diskstream() double _pixel_width; - double _height; bool in_destructor; bool wait_for_data; diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index 2749b9e73a..536fdfc9cb 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -136,7 +136,6 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie resizer.signal_expose_event().connect (mem_fun (*this, &TimeAxisView::resizer_expose)); resizer.signal_button_press_event().connect (mem_fun (*this, &TimeAxisView::resizer_button_press)); resizer.signal_button_release_event().connect (mem_fun (*this, &TimeAxisView::resizer_button_release)); - resizer.signal_motion_notify_event().connect (mem_fun (*this, &TimeAxisView::resizer_motion)); resizer.set_events (Gdk::BUTTON_PRESS_MASK| Gdk::BUTTON_RELEASE_MASK| Gdk::POINTER_MOTION_MASK| @@ -1212,6 +1211,10 @@ TimeAxisView::resizer_button_press (GdkEventButton* event) resize_drag_start = event->y_root; resize_idle_target = current_height(); editor.start_resize_line_ops (); + if (resizer_motion_signal) { + resizer_motion_signal.disconnect (); + } + resizer_motion_signal = resizer.signal_motion_notify_event().connect (mem_fun (*this, &TimeAxisView::resizer_motion)); return true; } @@ -1220,6 +1223,7 @@ TimeAxisView::resizer_button_release (GdkEventButton* ev) { resize_drag_start = -1; editor.end_resize_line_ops (); + resizer_motion_signal.disconnect (); return true; } @@ -1237,11 +1241,13 @@ TimeAxisView::resizer_motion (GdkEventMotion* ev) } int32_t delta = (int32_t) floor (resize_drag_start - ev->y_root); + int32_t target = resize_idle_target - delta; - resize_idle_target = std::max (resize_idle_target - delta, (int) hSmall); + resize_idle_target = std::max (target, (int) hSmall); editor.add_to_idle_resize (this, resize_idle_target); - - resize_drag_start = ev->y_root; + if (target >= (int) hSmall ) { + resize_drag_start = ev->y_root; + } return true; } diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index b186c49fb0..b624bda73a 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -122,6 +122,7 @@ class TimeAxisView : public virtual AxisView, public Stateful bool resizer_button_press (GdkEventButton*); bool resizer_button_release (GdkEventButton*); + sigc::connection resizer_motion_signal; bool resizer_motion (GdkEventMotion*); bool resizer_expose (GdkEventExpose*); diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc index 0d69ed74d5..ec0af7fb3b 100644 --- a/gtk2_ardour/time_axis_view_item.cc +++ b/gtk2_ardour/time_axis_view_item.cc @@ -49,6 +49,7 @@ bool TimeAxisViewItem::have_name_font = false; const double TimeAxisViewItem::NAME_X_OFFSET = 15.0; const double TimeAxisViewItem::GRAB_HANDLE_LENGTH = 6 ; +int TimeAxisViewItem::NAME_HEIGHT; double TimeAxisViewItem::NAME_Y_OFFSET; double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE; double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH; @@ -70,7 +71,7 @@ double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH; TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, bool recording, Visibility vis) - : trackview (tv), _recregion(recording) + : trackview (tv), _height(1.0), _recregion(recording) { if (!have_name_font) { @@ -89,7 +90,8 @@ 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 + 6; + NAME_HEIGHT = height; + NAME_Y_OFFSET = (height / 2) + 8; NAME_HIGHLIGHT_SIZE = height + 6; NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2; @@ -104,6 +106,7 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other) : trackview (other.trackview) + , _height (other._height) { Gdk::Color c; @@ -137,6 +140,8 @@ TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_colo show_vestigial = true; visibility = vis; _sensitive = true; + name_pixbuf_width = 0; + last_item_width = 0; if (duration == 0) { warning << "Time Axis Item Duration == 0" << endl ; @@ -543,46 +548,13 @@ TimeAxisViewItem::get_time_axis_view() void TimeAxisViewItem::set_name_text(const ustring& new_name) { - uint32_t pb_width, it_width; - double font_size; - - font_size = NAME_FONT->get_size() / Pango::SCALE; - it_width = trackview.editor.frame_to_pixel(item_duration); - pb_width = new_name.length() * font_size; - - if (pb_width > it_width - NAME_X_OFFSET) { - pb_width = it_width - NAME_X_OFFSET; - } - - if (pb_width <= 0 || it_width < NAME_X_OFFSET) { - if (name_pixbuf) { - name_pixbuf->hide(); - } + if (!name_pixbuf) { return; - } else { - name_pixbuf->show(); } - Glib::RefPtr buf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, pb_width, NAME_HIGHLIGHT_SIZE); - - cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, pb_width, NAME_HIGHLIGHT_SIZE ); - cairo_t *cr = cairo_create (surface); - cairo_text_extents_t te; - cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); - cairo_select_font_face (cr, NAME_FONT->get_family().c_str(), - CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); - cairo_set_font_size (cr, font_size); - cairo_text_extents (cr, new_name.c_str(), &te); - - cairo_move_to (cr, 0.5, - 0.5 - te.height / 2 - te.y_bearing + NAME_HIGHLIGHT_SIZE / 2); - cairo_show_text (cr, new_name.c_str()); - - unsigned char* src = cairo_image_surface_get_data (surface); - convert_bgra_to_rgba(src, buf->get_pixels(), pb_width, NAME_HIGHLIGHT_SIZE); - - cairo_destroy(cr); - name_pixbuf->property_pixbuf() = buf; + last_item_width = trackview.editor.frame_to_pixel(item_duration); + name_pixbuf_width = pixel_width (new_name, *NAME_FONT) + 2; + name_pixbuf->property_pixbuf() = pixbuf_from_ustring(new_name, NAME_FONT, name_pixbuf_width, NAME_HEIGHT); } /** @@ -593,15 +565,13 @@ TimeAxisViewItem::set_name_text(const ustring& new_name) void TimeAxisViewItem::set_height (double height) { + _height = height; + if (name_highlight) { if (height < NAME_HIGHLIGHT_THRESH) { name_highlight->hide(); - name_pixbuf->hide(); - } else { - name_highlight->show(); - name_pixbuf->show(); - + name_highlight->show(); } if (height > NAME_HIGHLIGHT_SIZE) { @@ -614,8 +584,13 @@ TimeAxisViewItem::set_height (double height) } } - if (visibility & ShowNameText) { - name_pixbuf->property_y() = height+1 - NAME_Y_OFFSET; + if (name_pixbuf) { + if (height < NAME_HIGHLIGHT_THRESH) { + name_pixbuf->hide(); + } else { + name_pixbuf->property_y() = height+1 - NAME_Y_OFFSET; + name_pixbuf->show(); + } } if (frame) { @@ -847,6 +822,9 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) if (name_highlight) { name_highlight->hide(); + } + + if (name_pixbuf) { name_pixbuf->hide(); } @@ -864,16 +842,10 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) if (name_highlight) { - double height = name_highlight->property_y2 (); - - if (height < NAME_HIGHLIGHT_THRESH) { + if (_height < NAME_HIGHLIGHT_THRESH) { name_highlight->hide(); - name_pixbuf->hide(); } else { name_highlight->show(); - if (!get_item_name().empty()) { - reset_name_width (pixel_width); - } } if (visibility & FullWidthNameHighlight) { @@ -884,6 +856,14 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) } + if (name_pixbuf) { + if (_height < NAME_HIGHLIGHT_THRESH) { + name_pixbuf->hide(); + } else { + reset_name_width (pixel_width); + } + } + if (frame) { frame->show(); frame->property_x2() = pixel_width; @@ -904,9 +884,42 @@ TimeAxisViewItem::reset_width_dependent_items (double pixel_width) } void -TimeAxisViewItem::reset_name_width (double pixel_width) +TimeAxisViewItem::reset_name_width (double pix_width) { - set_name_text (item_name); + uint32_t it_width; + int pb_width; + bool pixbuf_holds_full_name; + + if (!name_pixbuf) { + return; + } + + it_width = trackview.editor.frame_to_pixel(item_duration); + pb_width = name_pixbuf_width; + + pixbuf_holds_full_name = last_item_width > pb_width + NAME_X_OFFSET; + last_item_width = it_width; + + if (pixbuf_holds_full_name && (it_width >= pb_width + NAME_X_OFFSET)) { + /* + we've previously had the full name length showing + and its still showing. + */ + return; + } + + if (pb_width > it_width - NAME_X_OFFSET) { + pb_width = it_width - NAME_X_OFFSET; + } + + if (pb_width <= 0 || it_width <= NAME_X_OFFSET) { + name_pixbuf->hide(); + return; + } else { + name_pixbuf->show(); + } + + name_pixbuf->property_pixbuf() = pixbuf_from_ustring(item_name, NAME_FONT, pb_width, NAME_HEIGHT); } diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h index 41fc88d17f..9874be8cbb 100644 --- a/gtk2_ardour/time_axis_view_item.h +++ b/gtk2_ardour/time_axis_view_item.h @@ -200,7 +200,7 @@ class TimeAxisViewItem : public Selectable * @param new_name the new name text to display */ void set_name_text(const Glib::ustring& new_name) ; - + /** * Set the height of this item * @@ -273,6 +273,7 @@ class TimeAxisViewItem : public Selectable /* these are not constant, but vary with the pixel size of the font used to display the item name. */ + static int NAME_HEIGHT ; static double NAME_Y_OFFSET ; static double NAME_HIGHLIGHT_SIZE ; static double NAME_HIGHLIGHT_THRESH ; @@ -434,7 +435,7 @@ class TimeAxisViewItem : public Selectable */ bool show_vestigial; - uint32_t fill_opacity; + uint32_t fill_opacity; uint32_t fill_color ; uint32_t frame_color_r ; uint32_t frame_color_g ; @@ -450,7 +451,9 @@ class TimeAxisViewItem : public Selectable uint32_t lock_handle_color_r ; uint32_t lock_handle_color_g ; uint32_t lock_handle_color_b ; - + uint32_t last_item_width; + int name_pixbuf_width; + ArdourCanvas::Group* group; ArdourCanvas::SimpleRect* vestigial_frame; ArdourCanvas::SimpleRect* frame; @@ -459,6 +462,7 @@ class TimeAxisViewItem : public Selectable ArdourCanvas::SimpleRect* frame_handle_start; ArdourCanvas::SimpleRect* frame_handle_end; + double _height; Visibility visibility; bool _recregion; diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index d4228781de..fc43b4cde7 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -789,3 +789,30 @@ convert_bgra_to_rgba (guint8 const* src, src_pixel += 4; } } + +Glib::RefPtr +pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_width, int clip_height) +{ + + Glib::RefPtr buf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, 8, clip_width, clip_height); + cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, clip_width, clip_height); + cairo_t *cr = cairo_create (surface); + cairo_text_extents_t te; + unsigned char* src = cairo_image_surface_get_data (surface); + + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); + cairo_select_font_face (cr, font->get_family().c_str(), + CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size (cr, font->get_size() / Pango::SCALE); + cairo_text_extents (cr, name.c_str(), &te); + + cairo_move_to (cr, 0.5, 0.5 - te.height / 2 - te.y_bearing + clip_height / 2); + cairo_show_text (cr, name.c_str()); + + convert_bgra_to_rgba(src, buf->get_pixels(), clip_width, clip_height); + + delete [] src; + cairo_destroy(cr); + + return buf; +} diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h index 48ebfe2a4b..88c8536cc2 100644 --- a/gtk2_ardour/utils.h +++ b/gtk2_ardour/utils.h @@ -92,5 +92,9 @@ void convert_bgra_to_rgba (guint8 const* src, guint8* dst, int width, int height); +Glib::RefPtr pixbuf_from_ustring (const Glib::ustring& name, + Pango::FontDescription* font, + int clip_width, + int clip_height); #endif /* __ardour_gtk_utils_h__ */ -- cgit v1.2.3