Initial commit
[fillmore] / src / marina / TrackView.vala
diff --git a/src/marina/TrackView.vala b/src/marina/TrackView.vala
new file mode 100644 (file)
index 0000000..a0a80f6
--- /dev/null
@@ -0,0 +1,199 @@
+/* Copyright 2009-2010 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution. 
+ */
+
+using Logging;
+
+class TrackViewConcrete : TrackView, Gtk.Fixed {
+    Model.Track track;
+    TimeLine timeline;
+    TransportDelegate transport_delegate;
+
+    const int clip_height = 64;
+    const int TrackHeight = clip_height + TimeLine.BORDER * 2;
+
+    public TrackViewConcrete(TransportDelegate transport_delegate, 
+            Model.Track track, TimeLine timeline) {
+        this.track = track;
+        this.timeline = timeline;
+        this.transport_delegate = transport_delegate;
+
+        track.clip_added.connect(on_clip_added);
+        track.clip_removed.connect(on_clip_removed);
+    }
+
+    override void size_request(out Gtk.Requisition requisition) {
+        base.size_request(out requisition);
+        requisition.height = TrackHeight;
+        requisition.width += TimeLine.BORDER;    // right margin
+    }
+
+    void on_clip_moved(ClipView clip) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_moved");
+        set_clip_pos(clip);
+    }
+
+    void on_clip_deleted(Model.Clip clip) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_deleted");
+        track.delete_clip(clip);
+        clear_drag();
+    }
+
+    void on_clip_added(Model.Track t, Model.Clip clip, bool select) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_added");
+        ClipView view = new ClipView(transport_delegate, clip, timeline.provider, clip_height);
+        view.clip_moved.connect(on_clip_moved);
+        view.clip_deleted.connect(on_clip_deleted);
+        view.move_begin.connect(on_move_begin);
+        view.trim_begin.connect(on_trim_begin);
+
+        put(view, timeline.provider.time_to_xpos(clip.start), TimeLine.BORDER);
+        view.show();
+
+        timeline.track_changed();
+        clip_view_added(view);
+        if (select) {
+            view.selection_request(view, false);
+        }
+    }
+
+    // TODO: This method should not be public.  When linking/grouping is done, this method
+    // should become private.  See Timeline.on_clip_view_move_begin for more information.
+    public void move_to_top(ClipView clip_view) {
+        /*
+        * We remove the ClipView from the Fixed object and add it again to make
+        * sure that when we draw it, it is displayed above every other clip while
+        * dragging.
+        */
+        remove(clip_view);
+        put(clip_view, 
+            timeline.provider.time_to_xpos(clip_view.clip.start),
+            TimeLine.BORDER);
+        clip_view.show();
+    }
+
+    void on_trim_begin(ClipView clip_view) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_trim_begin");
+        move_to_top(clip_view);
+    }
+
+    void on_move_begin(ClipView clip_view, bool do_copy) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_move_begin");
+        move_to_top(clip_view);
+    }
+
+    void set_clip_pos(ClipView view) {
+        move(view, timeline.provider.time_to_xpos(view.clip.start), TimeLine.BORDER);
+        queue_draw();
+    }
+
+    public void resize() {
+        foreach (Gtk.Widget w in get_children()) {
+            ClipView view = w as ClipView;
+            if (view != null) {
+                view.on_clip_moved(view.clip);
+            }
+        }
+    }
+
+    void on_clip_removed(Model.Clip clip) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_clip_removed");
+        foreach (Gtk.Widget w in get_children()) {
+            ClipView view = w as ClipView;
+            if (view.clip == clip) {
+                view.clip_moved.disconnect(on_clip_moved);
+                remove(view);
+                timeline.track_changed();
+                return;
+            }
+        }
+    }
+
+/*
+    void unselect_gap() {
+        if (timeline.gap_view != null) {
+            TrackView parent = timeline.gap_view.parent as TrackView;
+            parent.remove(timeline.gap_view);
+            timeline.gap_view = null;
+        }
+    }
+*/
+
+    override bool button_press_event(Gdk.EventButton e) {
+        if (e.type != Gdk.EventType.BUTTON_PRESS &&
+            e.type != Gdk.EventType.2BUTTON_PRESS &&
+            e.type != Gdk.EventType.3BUTTON_PRESS)
+            return false;
+
+        if (e.button == 1 ||
+            e.button == 3) {
+/*
+            int x = (int) e.x;
+            int64 time = timeline.provider.xpos_to_time(x);
+            Model.Gap g;
+            track.find_containing_gap(time, out g);
+            if (g.end > g.start) {
+                int64 length = g.end - g.start;
+                int width = timeline.provider.time_to_xpos(g.start + length) -
+                    timeline.provider.time_to_xpos(g.start);            
+                
+                timeline.gap_view = new GapView(g.start, length, 
+                    width, clip_height);
+                timeline.gap_view.removed += on_gap_view_removed;
+                timeline.gap_view.unselected += on_gap_view_unselected;
+                put(timeline.gap_view, timeline.provider.time_to_xpos(g.start), TimeLine.BORDER);
+                timeline.gap_view.show();
+            }
+*/
+            timeline.deselect_all_clips();
+            /*
+            track.set_selected(true);
+            */
+        }
+        return false;
+    }
+    
+/*
+    void on_gap_view_removed(GapView gap_view) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_gap_view_removed");
+        track.delete_gap(gap_view.gap);
+    }
+
+    void on_gap_view_unselected(GapView gap_view) {
+        emit(this, Facility.SIGNAL_HANDLERS, Level.INFO, "on_gap_view_unselected");
+        unselect_gap();
+    }
+*/
+    void clear_drag() {
+        window.set_cursor(null);
+        queue_draw();
+    }
+
+    public Model.Track get_track() {
+        return track;
+    }
+    
+    public int get_track_height() {
+        return TrackHeight;
+    }
+    
+    public Gtk.Widget? find_child(double x, double y) {
+        foreach (Gtk.Widget w in get_children()) {
+            if (w.allocation.x <= x && x < w.allocation.x + w.allocation.width) {
+                return w;
+            }
+        }
+        return null;
+    }
+    
+    public void select_all() {
+        foreach (Gtk.Widget child in get_children()) {
+            ClipView? clip_view = child as ClipView;
+            if (clip_view != null) {
+                clip_view.select();
+            }
+        }
+    }
+}