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
This commit is contained in:
Nick Mainsbridge 2009-06-02 17:45:18 +00:00
parent beef5e20ce
commit 2641231cb2
12 changed files with 127 additions and 111 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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<Pango::Layout> 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;
int name_width = pixel_width (new_name, *name_font) + 2;
font_size = name_font->get_size() / Pango::SCALE;
pb_width = new_name.length() * font_size;
Glib::RefPtr<Gdk::Pixbuf> 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;
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);
}
}

View File

@ -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<Region> other_region)
@ -106,7 +104,6 @@ RegionView::RegionView (const RegionView& other, boost::shared_ptr<Region> 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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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*);

View File

@ -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<Gdk::Pixbuf> 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);
}

View File

@ -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;

View File

@ -789,3 +789,30 @@ convert_bgra_to_rgba (guint8 const* src,
src_pixel += 4;
}
}
Glib::RefPtr<Gdk::Pixbuf>
pixbuf_from_ustring(const ustring& name, Pango::FontDescription* font, int clip_width, int clip_height)
{
Glib::RefPtr<Gdk::Pixbuf> 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;
}

View File

@ -92,5 +92,9 @@ void convert_bgra_to_rgba (guint8 const* src,
guint8* dst,
int width,
int height);
Glib::RefPtr<Gdk::Pixbuf> pixbuf_from_ustring (const Glib::ustring& name,
Pango::FontDescription* font,
int clip_width,
int clip_height);
#endif /* __ardour_gtk_utils_h__ */