00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "timeline-ibeam-tool.hpp"
00024 #include "../timeline-widget.hpp"
00025
00026 using namespace gui::widgets;
00027
00028 namespace gui {
00029 namespace widgets {
00030 namespace timeline {
00031
00032
00033
00034 const int IBeamTool::DragZoneWidth = 5;
00035 const int IBeamTool::ScrollSlideRateDivisor = 16;
00036 const int IBeamTool::ScrollSlideEventInterval = 40;
00037
00038
00039
00040 IBeamTool::IBeamTool(TimelineBody *timeline_body) :
00041 dragType(None),
00042 pinnedDragTime(0),
00043 scrollSlideRate(0),
00044 Tool(timeline_body)
00045 {
00046
00047 }
00048
00049 IBeamTool::~IBeamTool()
00050 {
00051 end_scroll_slide();
00052 }
00053
00054 ToolType
00055 IBeamTool::get_type() const
00056 {
00057 return IBeam;
00058 }
00059
00060 Gdk::Cursor
00061 IBeamTool::get_cursor() const
00062 {
00063
00064
00065 switch(dragType)
00066 {
00067 case Selection:
00068 return Gdk::Cursor(Gdk::XTERM);
00069 case GrabStart:
00070 return Gdk::Cursor(Gdk::LEFT_SIDE);
00071 case GrabEnd:
00072 return Gdk::Cursor(Gdk::RIGHT_SIDE);
00073 }
00074
00075
00076
00077 if(is_mouse_in_start_drag_zone())
00078 return Gdk::Cursor(Gdk::LEFT_SIDE);
00079 if(is_mouse_in_end_drag_zone())
00080 return Gdk::Cursor(Gdk::RIGHT_SIDE);
00081
00082
00083 return Gdk::Cursor(Gdk::XTERM);
00084 }
00085
00086 void
00087 IBeamTool::on_button_press_event(GdkEventButton* event)
00088 {
00089 Tool::on_button_press_event(event);
00090
00091 TimelineWidget *timeline_widget = get_timeline_widget();
00092 REQUIRE(timeline_widget != NULL);
00093
00094 if(event->button == 1)
00095 {
00096 const gavl_time_t time =
00097 get_timeline_widget()->get_view_window().x_to_time(event->x);
00098
00099 if(is_mouse_in_start_drag_zone())
00100 {
00101
00102 dragType = GrabStart;
00103 pinnedDragTime = timeline_widget->get_selection_end();
00104 }
00105 else if(is_mouse_in_end_drag_zone())
00106 {
00107
00108 dragType = GrabEnd;
00109 pinnedDragTime = timeline_widget->get_selection_start();
00110 }
00111 else
00112 {
00113
00114 dragType = Selection;
00115 pinnedDragTime = time;
00116 timeline_widget->set_selection(time, time);
00117 }
00118 }
00119 }
00120
00121 void
00122 IBeamTool::on_button_release_event(GdkEventButton* event)
00123 {
00124
00125 ENSURE(isDragging == (dragType != None));
00126 ENSURE(isDragging == (event->button == 1));
00127
00128 if(event->button == 1)
00129 {
00130 set_leading_x(event->x);
00131
00132
00133 dragType = None;
00134
00135
00136 end_scroll_slide();
00137
00138
00139
00140 apply_cursor();
00141 }
00142
00143 Tool::on_button_release_event(event);
00144 }
00145
00146 void
00147 IBeamTool::on_motion_notify_event(GdkEventMotion *event)
00148 {
00149 Tool::on_motion_notify_event(event);
00150
00151
00152 ENSURE(isDragging == (dragType != None));
00153
00154 if(isDragging)
00155 {
00156 set_leading_x(event->x);
00157
00158
00159 const Gdk::Rectangle body_rect(get_body_rectangle());
00160 if(event->x < 0)
00161 begin_scroll_slide(
00162 event->x / ScrollSlideRateDivisor);
00163 else if(event->x > body_rect.get_width())
00164 begin_scroll_slide(
00165 (event->x - body_rect.get_width()) / ScrollSlideRateDivisor);
00166 else end_scroll_slide();
00167 }
00168
00169 apply_cursor();
00170 }
00171
00172 bool
00173 IBeamTool::on_scroll_slide_timer()
00174 {
00175 get_timeline_widget()->get_view_window().shift_view(scrollSlideRate);
00176
00177
00178 return true;
00179 }
00180
00181 void
00182 IBeamTool::set_leading_x(const int x)
00183 {
00184 TimelineWidget *timeline_widget = get_timeline_widget();
00185 REQUIRE(timeline_widget != NULL);
00186
00187 const bool set_playback_period = dragType == Selection;
00188 const gavl_time_t time =
00189 timeline_widget->get_view_window().x_to_time(x);
00190 if(time > pinnedDragTime)
00191 timeline_widget->set_selection(
00192 pinnedDragTime, time, set_playback_period);
00193 else
00194 timeline_widget->set_selection(
00195 time, pinnedDragTime, set_playback_period);
00196 }
00197
00198 void
00199 IBeamTool::begin_scroll_slide(int scroll_slide_rate)
00200 {
00201 scrollSlideRate = scroll_slide_rate;
00202 if(!scrollSlideEvent.connected())
00203 scrollSlideEvent = Glib::signal_timeout().connect(
00204 sigc::mem_fun(this, &IBeamTool::on_scroll_slide_timer),
00205 ScrollSlideEventInterval);
00206 }
00207
00208 void
00209 IBeamTool::end_scroll_slide()
00210 {
00211 scrollSlideRate = 0;
00212 if(scrollSlideEvent.connected())
00213 scrollSlideEvent.disconnect();
00214 }
00215
00216 bool
00217 IBeamTool::is_mouse_in_start_drag_zone() const
00218 {
00219 TimelineWidget *timeline_widget = get_timeline_widget();
00220
00221 const int start_x = timeline_widget->get_view_window().time_to_x(
00222 timeline_widget->get_selection_start());
00223
00224 return (mousePoint.get_x() <= start_x &&
00225 mousePoint.get_x() > start_x - DragZoneWidth);
00226 }
00227
00228 bool
00229 IBeamTool::is_mouse_in_end_drag_zone() const
00230 {
00231 TimelineWidget *timeline_widget = get_timeline_widget();
00232
00233 const int end_x = timeline_widget->get_view_window().time_to_x(
00234 timeline_widget->get_selection_end());
00235
00236 return (mousePoint.get_x() >= end_x &&
00237 mousePoint.get_x() < end_x + DragZoneWidth);
00238 }
00239
00240 }
00241 }
00242 }