diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 65e216f16..c90449124 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -245,7 +245,6 @@ TimelinePanel::update_sequence_chooser() shared_ptr state = timelineWidget->get_state(); - REQUIRE(state); BOOST_FOREACH( shared_ptr< model::Sequence > sequence, workspace.get_project().get_sequences() ) @@ -255,10 +254,14 @@ TimelinePanel::update_sequence_chooser() row[sequenceChooserColumns.sequenceColumn] = sequence; row[sequenceChooserColumns.nameColumn] = sequence->get_name(); - if(state->get_sequence() == sequence) + if(state && state->get_sequence() == sequence) sequenceChooser.set_active(iter); } + // If there's no active sequence, then unselect + if(!state) + sequenceChooser.set_active(-1); + // Unblock the event handler sequenceChooserChangedConnection.unblock(); } @@ -287,12 +290,17 @@ TimelinePanel::update_zoom_buttons() { REQUIRE(timelineWidget); - timeline::TimelineViewWindow &viewWindow = - timelineWidget->get_state()->get_view_window(); - - zoomIn.set_sensitive(viewWindow.get_time_scale() != 1); - zoomOut.set_sensitive(viewWindow.get_time_scale() - != TimelineWidget::MaxScale); + const shared_ptr state = + timelineWidget->get_state(); + if(state) + { + timeline::TimelineViewWindow &viewWindow = + state->get_view_window(); + + zoomIn.set_sensitive(viewWindow.get_time_scale() != 1); + zoomOut.set_sensitive(viewWindow.get_time_scale() + != TimelineWidget::MaxScale); + } } void diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 387927ce1..1c38b081a 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -51,11 +51,8 @@ TimelineWidget::TimelineWidget( verticalAdjustment(0, 0, 0), horizontalScroll(horizontalAdjustment), verticalScroll(verticalAdjustment), - update_tracks_frozen(true) + update_tracks_frozen(false) { - set_state(source_state); - thaw_update_tracks(); - body = new TimelineBody(*this); ENSURE(body != NULL); headerContainer = new TimelineHeaderContainer(*this); @@ -78,6 +75,8 @@ TimelineWidget::TimelineWidget( attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); + set_state(source_state); + set_tool(timeline::Arrow); } @@ -102,34 +101,32 @@ TimelineWidget::~TimelineWidget() boost::shared_ptr TimelineWidget::get_state() { - ENSURE(state); return state; } void TimelineWidget::set_state(shared_ptr new_state) -{ - if(!new_state) - return; - +{ state = new_state; - REQUIRE(state); // Clear the track tree trackMap.clear(); - // Hook up event handlers - state->get_view_window().changed_signal().connect( sigc::mem_fun( - this, &TimelineWidget::on_view_window_changed) ); - state->get_sequence()->get_child_track_list().signal_changed(). - connect(sigc::mem_fun( - this, &TimelineWidget::on_track_list_changed ) ); - - state->selection_changed_signal().connect(mem_fun(*this, - &TimelineWidget::on_body_changed)); - state->playback_changed_signal().connect(mem_fun(*this, - &TimelineWidget::on_body_changed)); - + if(state) + { + // Hook up event handlers + state->get_view_window().changed_signal().connect( sigc::mem_fun( + this, &TimelineWidget::on_view_window_changed) ); + state->get_sequence()->get_child_track_list().signal_changed(). + connect(sigc::mem_fun( + this, &TimelineWidget::on_track_list_changed ) ); + + state->selection_changed_signal().connect(mem_fun(*this, + &TimelineWidget::on_body_changed)); + state->playback_changed_signal().connect(mem_fun(*this, + &TimelineWidget::on_body_changed)); + } + update_tracks(); // Send the state changed signal @@ -139,10 +136,11 @@ TimelineWidget::set_state(shared_ptr new_state) void TimelineWidget::zoom_view(int zoom_size) { - REQUIRE(state); - - const int view_width = body->get_allocation().get_width(); - state->get_view_window().zoom_view(view_width / 2, zoom_size); + if(state) + { + const int view_width = body->get_allocation().get_width(); + state->get_view_window().zoom_view(view_width / 2, zoom_size); + } } ToolType @@ -195,9 +193,9 @@ TimelineWidget::state_changed_signal() const void TimelineWidget::on_scroll() { - REQUIRE(state); - state->get_view_window().set_time_offset( - horizontalAdjustment.get_value()); + if(state) + state->get_view_window().set_time_offset( + horizontalAdjustment.get_value()); } void @@ -212,14 +210,16 @@ void TimelineWidget::on_view_window_changed() { REQUIRE(ruler != NULL); - REQUIRE(state); - - timeline::TimelineViewWindow &window = state->get_view_window(); - const int view_width = body->get_allocation().get_width(); - horizontalAdjustment.set_page_size( - window.get_time_scale() * view_width); - horizontalAdjustment.set_value(window.get_time_offset()); + if(state) + { + timeline::TimelineViewWindow &window = state->get_view_window(); + const int view_width = body->get_allocation().get_width(); + + horizontalAdjustment.set_page_size( + window.get_time_scale() * view_width); + horizontalAdjustment.set_value(window.get_time_offset()); + } } void @@ -235,8 +235,9 @@ void TimelineWidget::on_add_track_command() { // # TEST CODE - sequence()->get_child_track_list().push_back( - shared_ptr(new model::ClipTrack())); + if(sequence()) + sequence()->get_child_track_list().push_back( + shared_ptr(new model::ClipTrack())); } /* ===== Internals ===== */ @@ -247,15 +248,20 @@ TimelineWidget::update_tracks() if(update_tracks_frozen) return; - // Remove any tracks which are no longer present in the model - remove_orphaned_tracks(); - - // Create timeline tracks from all the model tracks - create_timeline_tracks(); - - // Update the layout helper - layoutHelper.clone_tree_from_sequence(); - layoutHelper.update_layout(); + if(state) + { + // Remove any tracks which are no longer present in the model + remove_orphaned_tracks(); + + // Create timeline tracks from all the model tracks + create_timeline_tracks(); + + // Update the layout helper + layoutHelper.clone_tree_from_sequence(); + layoutHelper.update_layout(); + } + else + trackMap.clear(); } void @@ -273,6 +279,8 @@ TimelineWidget::thaw_update_tracks() void TimelineWidget::create_timeline_tracks() { + REQUIRE(state); + BOOST_FOREACH(shared_ptr child, sequence()->get_child_tracks()) create_timeline_tracks_from_branch(child); @@ -403,44 +411,45 @@ TimelineWidget::update_scroll() REQUIRE(body != NULL); const Allocation body_allocation = body->get_allocation(); - REQUIRE(state); - timeline::TimelineViewWindow &window = state->get_view_window(); - - //----- Horizontal Scroll ------// - - // TEST CODE - horizontalAdjustment.set_upper(1000 * GAVL_TIME_SCALE / 200); - horizontalAdjustment.set_lower(-1000 * GAVL_TIME_SCALE / 200); - - // Set the page size - horizontalAdjustment.set_page_size( - window.get_time_scale() * body_allocation.get_width()); - - //----- Vertical Scroll -----// - - // Calculate the vertical length that can be scrolled: - // the total height of all the tracks minus one screenful - int y_scroll_length = layoutHelper.get_total_height() - - body_allocation.get_height(); - if(y_scroll_length < 0) y_scroll_length = 0; - - // If by resizing we're now over-scrolled, scroll back to - // maximum distance - if((int)verticalAdjustment.get_value() > y_scroll_length) - verticalAdjustment.set_value(y_scroll_length); - - verticalAdjustment.set_upper(y_scroll_length); - - // Hide the scrollbar if no scrolling is possible + if(state) + { + timeline::TimelineViewWindow &window = state->get_view_window(); + + //----- Horizontal Scroll ------// + + // TEST CODE + horizontalAdjustment.set_upper(1000 * GAVL_TIME_SCALE / 200); + horizontalAdjustment.set_lower(-1000 * GAVL_TIME_SCALE / 200); + + // Set the page size + horizontalAdjustment.set_page_size( + window.get_time_scale() * body_allocation.get_width()); + + //----- Vertical Scroll -----// + + // Calculate the vertical length that can be scrolled: + // the total height of all the tracks minus one screenful + int y_scroll_length = layoutHelper.get_total_height() - + body_allocation.get_height(); + if(y_scroll_length < 0) y_scroll_length = 0; + + // If by resizing we're now over-scrolled, scroll back to + // maximum distance + if((int)verticalAdjustment.get_value() > y_scroll_length) + verticalAdjustment.set_value(y_scroll_length); + + verticalAdjustment.set_upper(y_scroll_length); + + // Hide the scrollbar if no scrolling is possible #if 0 - // Having this code included seems to cause a layout loop as the - // window is shrunk - if(y_scroll_length <= 0 && verticalScroll.is_visible()) - verticalScroll.hide(); - else if(y_scroll_length > 0 && !verticalScroll.is_visible()) - verticalScroll.show(); + // Having this code included seems to cause a layout loop as the + // window is shrunk + if(y_scroll_length <= 0 && verticalScroll.is_visible()) + verticalScroll.hide(); + else if(y_scroll_length > 0 && !verticalScroll.is_visible()) + verticalScroll.show(); #endif - + } } int @@ -461,9 +470,11 @@ TimelineWidget::on_motion_in_body_notify_event(GdkEventMotion *event) REQUIRE(event != NULL); ruler->set_mouse_chevron_offset(event->x); - REQUIRE(state); - timeline::TimelineViewWindow &window = state->get_view_window(); - mouseHoverSignal.emit(window.x_to_time(event->x)); + if(state) + { + timeline::TimelineViewWindow &window = state->get_view_window(); + mouseHoverSignal.emit(window.x_to_time(event->x)); + } return true; } @@ -471,8 +482,9 @@ TimelineWidget::on_motion_in_body_notify_event(GdkEventMotion *event) boost::shared_ptr TimelineWidget::sequence() const { - REQUIRE(state); - boost::shared_ptr sequence = state->get_sequence(); + if(!state) + return shared_ptr(); + shared_ptr sequence = state->get_sequence(); ENSURE(sequence); return sequence; } diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index 3d52f7fe5..b3077f00d 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -137,16 +137,19 @@ TimelineBody::on_expose_event(GdkEventExpose* event) // Makes sure the widget styles have been loaded read_styles(); - // Prepare to render via cairo - const Allocation allocation = get_allocation(); - Cairo::RefPtr cr = window->create_cairo_context(); + if(timelineWidget.get_state()) + { + // Prepare to render via cairo + const Allocation allocation = get_allocation(); + Cairo::RefPtr cr = window->create_cairo_context(); - REQUIRE(cr); - - //----- Draw the view -----// - draw_tracks(cr); - draw_selection(cr); - draw_playback_point(cr); + REQUIRE(cr); + + //----- Draw the view -----// + draw_tracks(cr); + draw_selection(cr); + draw_playback_point(cr); + } return true; } @@ -156,45 +159,48 @@ TimelineBody::on_scroll_event (GdkEventScroll* event) { REQUIRE(event != NULL); - TimelineViewWindow &window = view_window(); - const Allocation allocation = get_allocation(); - - if(event->state & GDK_CONTROL_MASK) - { - switch(event->direction) + if(timelineWidget.get_state()) { - case GDK_SCROLL_UP: - // User scrolled up. Zoom in - window.zoom_view(event->x, 1); - break; + TimelineViewWindow &window = view_window(); + const Allocation allocation = get_allocation(); - case GDK_SCROLL_DOWN: - // User scrolled down. Zoom out - window.zoom_view(event->x, -1); - break; - - default: - break; + if(event->state & GDK_CONTROL_MASK) + { + switch(event->direction) + { + case GDK_SCROLL_UP: + // User scrolled up. Zoom in + window.zoom_view(event->x, 1); + break; + + case GDK_SCROLL_DOWN: + // User scrolled down. Zoom out + window.zoom_view(event->x, -1); + break; + + default: + break; + } + } + else + { + switch(event->direction) + { + case GDK_SCROLL_UP: + // User scrolled up. Shift 1/16th left + window.shift_view(allocation.get_width(), -16); + break; + + case GDK_SCROLL_DOWN: + // User scrolled down. Shift 1/16th right + window.shift_view(allocation.get_width(), 16); + break; + + default: + break; + } + } } - } - else - { - switch(event->direction) - { - case GDK_SCROLL_UP: - // User scrolled up. Shift 1/16th left - window.shift_view(allocation.get_width(), -16); - break; - - case GDK_SCROLL_DOWN: - // User scrolled down. Shift 1/16th right - window.shift_view(allocation.get_width(), 16); - break; - - default: - break; - } - } return true; } @@ -239,36 +245,39 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event) { REQUIRE(event != NULL); - // Handle a middle-mouse drag if one is occuring - switch(dragType) + if(timelineWidget.get_state()) { - case Shift: - { - TimelineViewWindow &window = view_window(); - - const int64_t scale = window.get_time_scale(); - gavl_time_t offset = beginShiftTimeOffset + - (int64_t)(mouseDownX - event->x) * scale; - window.set_time_offset(offset); - - set_vertical_offset((int)(mouseDownY - event->y) + - beginShiftVerticalOffset); - break; - } + // Handle a middle-mouse drag if one is occuring + switch(dragType) + { + case Shift: + { + TimelineViewWindow &window = view_window(); + + const int64_t scale = window.get_time_scale(); + gavl_time_t offset = beginShiftTimeOffset + + (int64_t)(mouseDownX - event->x) * scale; + window.set_time_offset(offset); + + set_vertical_offset((int)(mouseDownY - event->y) + + beginShiftVerticalOffset); + break; + } + + default: + break; + } - default: - break; + // Forward the event to the tool + tool->on_motion_notify_event(event); + + // See if the track that we're hovering over has changed + shared_ptr new_hovering_track( + timelineWidget.layoutHelper.track_from_y(event->y)); + if(timelineWidget.get_hovering_track() != new_hovering_track) + timelineWidget.set_hovering_track(new_hovering_track); } - // Forward the event to the tool - tool->on_motion_notify_event(event); - - // See if the track that we're hovering over has changed - shared_ptr new_hovering_track( - timelineWidget.layoutHelper.track_from_y(event->y)); - if(timelineWidget.get_hovering_track() != new_hovering_track) - timelineWidget.set_hovering_track(new_hovering_track); - // false so that the message is passed up to the owner TimelineWidget return false; } @@ -276,9 +285,12 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event) void TimelineBody::on_state_changed() { - // Connect up some events - view_window().changed_signal().connect( - sigc::mem_fun(this, &TimelineBody::on_update_view) ); + if(timelineWidget.get_state()) + { + // Connect up some events + view_window().changed_signal().connect( + sigc::mem_fun(this, &TimelineBody::on_update_view) ); + } // Redraw queue_draw(); @@ -299,6 +311,9 @@ TimelineBody::draw_tracks(Cairo::RefPtr cr) Cairo::Matrix view_matrix; cr->get_matrix(view_matrix); + // If the tree's empty that means there's no sequence root + REQUIRE(!layout_tree.empty()); + // Iterate drawing each track TimelineLayoutHelper::TrackTree::pre_order_iterator iterator; for(iterator = ++layout_tree.begin(); // ++ so we skip the sequence root @@ -408,35 +423,39 @@ TimelineBody::draw_playback_point(Cairo::RefPtr cr) // Prepare shared_ptr state = timelineWidget.get_state(); - REQUIRE(state); - - const Allocation allocation = get_allocation(); - - const gavl_time_t point = state->get_playback_point(); - if(point == (gavl_time_t)GAVL_TIME_UNDEFINED) - return; - - const int x = view_window().time_to_x(point); - - // Set source - gdk_cairo_set_source_color(cr->cobj(), &playbackPointColour); - cr->set_line_width(1); - - // Draw - if(x >= 0 && x < allocation.get_width()) + if(state) { - cr->move_to(x + 0.5, 0); - cr->line_to(x + 0.5, allocation.get_height()); - cr->stroke(); + const Allocation allocation = get_allocation(); + + const gavl_time_t point = state->get_playback_point(); + if(point == (gavl_time_t)GAVL_TIME_UNDEFINED) + return; + + const int x = view_window().time_to_x(point); + + // Set source + gdk_cairo_set_source_color(cr->cobj(), &playbackPointColour); + cr->set_line_width(1); + + // Draw + if(x >= 0 && x < allocation.get_width()) + { + cr->move_to(x + 0.5, 0); + cr->line_to(x + 0.5, allocation.get_height()); + cr->stroke(); + } } } void TimelineBody::begin_shift_drag() { - dragType = Shift; - beginShiftTimeOffset = view_window().get_time_offset(); - beginShiftVerticalOffset = get_vertical_offset(); + if(timelineWidget.get_state()) + { + dragType = Shift; + beginShiftTimeOffset = view_window().get_time_offset(); + beginShiftVerticalOffset = get_vertical_offset(); + } } int diff --git a/src/gui/widgets/timeline/timeline-body.hpp b/src/gui/widgets/timeline/timeline-body.hpp index 0cb351021..e218ae3a4 100644 --- a/src/gui/widgets/timeline/timeline-body.hpp +++ b/src/gui/widgets/timeline/timeline-body.hpp @@ -150,6 +150,8 @@ private: /** * A helper function to get the view window + * @remarks This function must not be called unless the TimlineWidget + * has a valid state. **/ TimelineViewWindow& view_window() const; diff --git a/src/gui/widgets/timeline/timeline-header-container.cpp b/src/gui/widgets/timeline/timeline-header-container.cpp index 9e4a60512..e8fa1ee52 100644 --- a/src/gui/widgets/timeline/timeline-header-container.cpp +++ b/src/gui/widgets/timeline/timeline-header-container.cpp @@ -241,16 +241,20 @@ TimelineHeaderContainer::on_size_request (Requisition* requisition) const TimelineLayoutHelper::TrackTree &layout_tree = timelineWidget.layoutHelper.get_layout_tree(); - - TimelineLayoutHelper::TrackTree::pre_order_iterator iterator; - for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root - iterator != layout_tree.end(); - iterator++) + + // Send a size request to all the children + if(!layout_tree.empty()) { - Widget &widget = - lookup_timeline_track(*iterator)->get_header_widget(); - if(widget.is_visible()) - widget.size_request(); + TimelineLayoutHelper::TrackTree::pre_order_iterator iterator; + for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root + iterator != layout_tree.end(); + iterator++) + { + Widget &widget = + lookup_timeline_track(*iterator)->get_header_widget(); + if(widget.is_visible()) + widget.size_request(); + } } // Initialize the output parameter: @@ -348,45 +352,48 @@ TimelineHeaderContainer::layout_headers() timelineWidget.layoutHelper; const TimelineLayoutHelper::TrackTree &layout_tree = layout_helper.get_layout_tree(); - - TimelineLayoutHelper::TrackTree::pre_order_iterator iterator; - for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root - iterator != layout_tree.end(); - iterator++) - { - const shared_ptr timeline_track = - lookup_timeline_track(*iterator); - - Widget &widget = timeline_track->get_header_widget(); - - optional header_rect = - layout_helper.get_track_header_rect(timeline_track); - - if(header_rect) - { - REQUIRE(header_rect->get_width() >= 0); - REQUIRE(header_rect->get_height() >= 0); - - // Apply the allocation to the header - widget.size_allocate (*header_rect); - if(!widget.is_visible()) - { - widget.show(); - headers_shown = true; - } - } - else // No header rect, so the track must be hidden - if(widget.is_visible()) - widget.hide(); - } - // If headers have been shown while we're dragging, the dragging - // branch headers have to be brought back to the top again - if(headers_shown && layout_helper.is_dragging_track()) - raise_recursive(layout_helper.get_dragging_track_iter()); - - // Repaint the background of our parenting - queue_draw(); + if(!layout_tree.empty()) + { + TimelineLayoutHelper::TrackTree::pre_order_iterator iterator; + for(iterator = ++layout_tree.begin(); // ++ so that we skip the sequence root + iterator != layout_tree.end(); + iterator++) + { + const shared_ptr timeline_track = + lookup_timeline_track(*iterator); + + Widget &widget = timeline_track->get_header_widget(); + + optional header_rect = + layout_helper.get_track_header_rect(timeline_track); + + if(header_rect) + { + REQUIRE(header_rect->get_width() >= 0); + REQUIRE(header_rect->get_height() >= 0); + + // Apply the allocation to the header + widget.size_allocate (*header_rect); + if(!widget.is_visible()) + { + widget.show(); + headers_shown = true; + } + } + else // No header rect, so the track must be hidden + if(widget.is_visible()) + widget.hide(); + } + + // If headers have been shown while we're dragging, the dragging + // branch headers have to be brought back to the top again + if(headers_shown && layout_helper.is_dragging_track()) + raise_recursive(layout_helper.get_dragging_track_iter()); + + // Repaint the background of our parenting + queue_draw(); + } } shared_ptr diff --git a/src/gui/widgets/timeline/timeline-ruler.cpp b/src/gui/widgets/timeline/timeline-ruler.cpp index fe117c39d..ac1922810 100644 --- a/src/gui/widgets/timeline/timeline-ruler.cpp +++ b/src/gui/widgets/timeline/timeline-ruler.cpp @@ -62,11 +62,14 @@ TimelineRuler::TimelineRuler( playbackPeriodArrowSize(10), playbackPeriodArrowStemSize(3), timelineWidget(timeline_widget) -{ - // Connect event handlers - view_window().changed_signal().connect( - sigc::mem_fun(this, &TimelineRuler::on_update_view) ); - +{ + if(timelineWidget.get_state()) + { + // Connect event handlers + view_window().changed_signal().connect( + sigc::mem_fun(this, &TimelineRuler::on_update_view) ); + } + // Install style properties register_styles(); } @@ -109,41 +112,44 @@ TimelineRuler::on_expose_event(GdkEventExpose* event) Glib::RefPtr window = get_window(); if(!window) return false; - - // Prepare to render via cairo - const Allocation allocation = get_allocation(); - - Cairo::RefPtr cr = window->create_cairo_context(); - REQUIRE(cr); - - // Draw the ruler - if(!rulerImage) + + if(timelineWidget.get_state()) { - // We have no cached rendering - it must be redrawn - // but do we need ro allocate a new image? - if(!rulerImage || - rulerImage->get_width() != allocation.get_width() || - rulerImage->get_height() != allocation.get_height()) - rulerImage = ImageSurface::create(FORMAT_RGB24, - allocation.get_width(), allocation.get_height()); + // Prepare to render via cairo + const Allocation allocation = get_allocation(); + + Cairo::RefPtr cr = window->create_cairo_context(); + REQUIRE(cr); + + // Draw the ruler + if(!rulerImage) + { + // We have no cached rendering - it must be redrawn + // but do we need ro allocate a new image? + if(!rulerImage || + rulerImage->get_width() != allocation.get_width() || + rulerImage->get_height() != allocation.get_height()) + rulerImage = ImageSurface::create(FORMAT_RGB24, + allocation.get_width(), allocation.get_height()); + + ENSURE(rulerImage); + + Cairo::RefPtr image_cairo = Context::create(rulerImage); + ENSURE(image_cairo); - ENSURE(rulerImage); - - Cairo::RefPtr image_cairo = Context::create(rulerImage); - ENSURE(image_cairo); + draw_ruler(image_cairo, allocation); + } - draw_ruler(image_cairo, allocation); + // Draw the cached ruler image + cr->set_source(rulerImage, 0, 0); + cr->paint(); + + // Draw the overlays + draw_mouse_chevron(cr, allocation); + draw_selection(cr, allocation); + draw_playback_period(cr, allocation); + draw_playback_point(cr, allocation); } - - // Draw the cached ruler image - cr->set_source(rulerImage, 0, 0); - cr->paint(); - - // Draw the overlays - draw_mouse_chevron(cr, allocation); - draw_selection(cr, allocation); - draw_playback_period(cr, allocation); - draw_playback_point(cr, allocation); return true; } @@ -153,11 +159,14 @@ TimelineRuler::on_button_press_event(GdkEventButton* event) { REQUIRE(event != NULL); - if(event->button == 1) - { - pinnedDragTime = view_window().x_to_time(event->x); - isDragging = true; - } + if(timelineWidget.get_state()) + { + if(event->button == 1) + { + pinnedDragTime = view_window().x_to_time(event->x); + isDragging = true; + } + } return true; } @@ -212,13 +221,15 @@ void TimelineRuler::set_leading_x(const int x) { shared_ptr state = timelineWidget.get_state(); - REQUIRE(state); - const gavl_time_t time = view_window().x_to_time(x); - if(time > pinnedDragTime) - state->set_playback_period(pinnedDragTime, time); - else - state->set_playback_period(time, pinnedDragTime); + if(state) + { + const gavl_time_t time = view_window().x_to_time(x); + if(time > pinnedDragTime) + state->set_playback_period(pinnedDragTime, time); + else + state->set_playback_period(time, pinnedDragTime); + } } void