1 /* Copyright 2009-2010 Yorba Foundation
3 * This software is licensed under the GNU Lesser General Public License
4 * (version 2.1 or later). See the COPYING file in this distribution.
9 class TrackViewConcrete : TrackView, Gtk.Fixed {
12 TransportDelegate transport_delegate;
14 const int clip_height = 64;
15 const int TrackHeight = clip_height + TimeLine.BORDER * 2;
17 public TrackViewConcrete(TransportDelegate transport_delegate,
18 Model.Track track, TimeLine timeline) {
20 this.timeline = timeline;
21 this.transport_delegate = transport_delegate;
23 track.clip_added.connect(on_clip_added);
24 track.clip_removed.connect(on_clip_removed);
27 override void size_request(out Gtk.Requisition requisition) {
28 base.size_request(out requisition);
29 requisition.height = TrackHeight;
30 requisition.width += TimeLine.BORDER; // right margin
33 void on_clip_moved(ClipView clip) {
34 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_moved");
38 void on_clip_deleted(Model.Clip clip) {
39 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_deleted");
40 track.delete_clip(clip);
44 void on_clip_added(Model.Track t, Model.Clip clip, bool select) {
45 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_added");
46 ClipView view = new ClipView(transport_delegate, clip, timeline.provider, clip_height);
47 view.clip_moved.connect(on_clip_moved);
48 view.clip_deleted.connect(on_clip_deleted);
49 view.move_begin.connect(on_move_begin);
50 view.trim_begin.connect(on_trim_begin);
52 put(view, timeline.provider.time_to_xpos(clip.start), TimeLine.BORDER);
55 timeline.track_changed();
56 clip_view_added(view);
58 view.selection_request(view, false);
62 // TODO: This method should not be public. When linking/grouping is done, this method
63 // should become private. See Timeline.on_clip_view_move_begin for more information.
64 public void move_to_top(ClipView clip_view) {
66 * We remove the ClipView from the Fixed object and add it again to make
67 * sure that when we draw it, it is displayed above every other clip while
72 timeline.provider.time_to_xpos(clip_view.clip.start),
77 void on_trim_begin(ClipView clip_view) {
78 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_trim_begin");
79 move_to_top(clip_view);
82 void on_move_begin(ClipView clip_view, bool do_copy) {
83 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_move_begin");
84 move_to_top(clip_view);
87 void set_clip_pos(ClipView view) {
88 move(view, timeline.provider.time_to_xpos(view.clip.start), TimeLine.BORDER);
92 public void resize() {
93 foreach (Gtk.Widget w in get_children()) {
94 ClipView view = w as ClipView;
96 view.on_clip_moved(view.clip);
101 void on_clip_removed(Model.Clip clip) {
102 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_removed");
103 foreach (Gtk.Widget w in get_children()) {
104 ClipView view = w as ClipView;
105 if (view.clip == clip) {
106 view.clip_moved.disconnect(on_clip_moved);
108 timeline.track_changed();
115 void unselect_gap() {
116 if (timeline.gap_view != null) {
117 TrackView parent = timeline.gap_view.parent as TrackView;
118 parent.remove(timeline.gap_view);
119 timeline.gap_view = null;
124 override bool button_press_event(Gdk.EventButton e) {
125 if (e.type != Gdk.EventType.BUTTON_PRESS &&
126 e.type != Gdk.EventType.2BUTTON_PRESS &&
127 e.type != Gdk.EventType.3BUTTON_PRESS)
134 int64 time = timeline.provider.xpos_to_time(x);
136 track.find_containing_gap(time, out g);
137 if (g.end > g.start) {
138 int64 length = g.end - g.start;
139 int width = timeline.provider.time_to_xpos(g.start + length) -
140 timeline.provider.time_to_xpos(g.start);
142 timeline.gap_view = new GapView(g.start, length,
144 timeline.gap_view.removed += on_gap_view_removed;
145 timeline.gap_view.unselected += on_gap_view_unselected;
146 put(timeline.gap_view, timeline.provider.time_to_xpos(g.start), TimeLine.BORDER);
147 timeline.gap_view.show();
150 timeline.deselect_all_clips();
152 track.set_selected(true);
159 void on_gap_view_removed(GapView gap_view) {
160 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_gap_view_removed");
161 track.delete_gap(gap_view.gap);
164 void on_gap_view_unselected(GapView gap_view) {
165 emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_gap_view_unselected");
170 window.set_cursor(null);
174 public Model.Track get_track() {
178 public int get_track_height() {
182 public Gtk.Widget? find_child(double x, double y) {
183 foreach (Gtk.Widget w in get_children()) {
184 if (w.allocation.x <= x && x < w.allocation.x + w.allocation.width) {
191 public void select_all() {
192 foreach (Gtk.Widget child in get_children()) {
193 ClipView? clip_view = child as ClipView;
194 if (clip_view != null) {