[hamster-applet] ooh, multi level tasks? what you don't say!



commit 1df23ed22a4d013a8dc2d4a6b1160893eafe765e
Author: Toms Bauģis <toms baugis gmail com>
Date:   Fri Apr 9 17:18:22 2010 +0100

    ooh, multi level tasks? what you don't say!

 data/edit_activity.ui          |   31 ++--
 src/hamster/edit_activity.py   |   17 +-
 src/hamster/widgets/dayline.py |  485 ++++++++++++++++------------------------
 3 files changed, 225 insertions(+), 308 deletions(-)
---
diff --git a/data/edit_activity.ui b/data/edit_activity.ui
index 039ee4e..ef3956a 100644
--- a/data/edit_activity.ui
+++ b/data/edit_activity.ui
@@ -15,7 +15,6 @@
     <child>
       <object class="GtkVBox" id="vbox2">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
         <child>
           <object class="GtkTable" id="table1">
             <property name="visible">True</property>
@@ -25,7 +24,7 @@
             <property name="row_spacing">6</property>
             <child>
               <object class="GtkEventBox" id="day_preview">
-                <property name="height_request">56</property>
+                <property name="height_request">70</property>
                 <property name="visible">True</property>
                 <child>
                   <placeholder/>
@@ -164,18 +163,6 @@
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="label4">
-                <property name="visible">True</property>
-                <property name="xalign">0</property>
-                <property name="yalign">0</property>
-                <property name="label" translatable="yes">Preview:</property>
-              </object>
-              <packing>
-                <property name="top_attach">4</property>
-                <property name="bottom_attach">5</property>
-              </packing>
-            </child>
-            <child>
               <object class="GtkLabel" id="Description:">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
@@ -246,6 +233,18 @@
                 <property name="bottom_attach">2</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel" id="label4">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="yalign">0</property>
+                <property name="label" translatable="yes">Preview:</property>
+              </object>
+              <packing>
+                <property name="top_attach">4</property>
+                <property name="bottom_attach">5</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -267,6 +266,8 @@
                 <signal name="clicked" handler="on_cancel_clicked"/>
               </object>
               <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
                 <property name="position">0</property>
               </packing>
             </child>
@@ -280,6 +281,8 @@
                 <signal name="clicked" handler="on_save_button_clicked"/>
               </object>
               <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
                 <property name="position">1</property>
               </packing>
             </child>
diff --git a/src/hamster/edit_activity.py b/src/hamster/edit_activity.py
index 5cf2065..0ceca35 100644
--- a/src/hamster/edit_activity.py
+++ b/src/hamster/edit_activity.py
@@ -108,8 +108,7 @@ class CustomFactController:
 
 
         self.dayline = widgets.DayLine()
-        self.dayline.on_time_changed = self.update_time
-        self.dayline.on_more_data = runtime.storage.get_facts
+        self.dayline.connect("on-time-chosen", self.update_time)
         self._gui.get_object("day_preview").add(self.dayline)
 
         self.on_in_progress_toggled(self.get_widget("in_progress"))
@@ -122,16 +121,20 @@ class CustomFactController:
 
         self.window.show_all()
 
-    def update_time(self, start_time, end_time):
+    def update_time(self, widget, start_time, end_time):
         self.start_time.set_time(start_time)
         self.start_date.set_date(start_time)
-        self.end_time.set_time(end_time)
-        self.set_end_date_label(end_time)
+
+        self.get_widget("in_progress").set_active(end_time is None)
+
+        if end_time:
+            self.end_time.set_time(end_time)
+            self.set_end_date_label(end_time)
 
 
     def draw_preview(self, date, highlight = None):
         day_facts = runtime.storage.get_facts(date)
-        self.dayline.draw(day_facts, highlight)
+        self.dayline.add_facts(day_facts, highlight)
 
     def get_widget(self, name):
         """ skip one variable (huh) """
@@ -222,7 +225,7 @@ class CustomFactController:
         self.get_widget("end_label").set_sensitive(sensitive)
         self.get_widget("end_date_label").set_sensitive(sensitive)
         self.validate_fields()
-        self.dayline.set_in_progress(not sensitive)
+        #self.dayline.set_in_progress(not sensitive)
 
     def on_cancel_clicked(self, button):
         self.close_window()
diff --git a/src/hamster/widgets/dayline.py b/src/hamster/widgets/dayline.py
index c41b95f..0073578 100644
--- a/src/hamster/widgets/dayline.py
+++ b/src/hamster/widgets/dayline.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 
-# Copyright (C) 2007-2009 Toms Bauģis <toms.baugis at gmail.com>
+# Copyright (C) 2007-2010 Toms Bauģis <toms.baugis at gmail.com>
 
 # This file is part of Project Hamster.
 
@@ -20,347 +20,258 @@
 import gtk
 import gobject
 
+import time
+import datetime as dt
+
 from .hamster import stuff
 from .hamster import graphics, pytweener
+from .hamster.configuration import conf
 
-import time
-import datetime as dt
-import colorsys
-import pango
 
+class Selection(graphics.Shape):
+    def __init__(self, start_time = None, end_time = None):
+        graphics.Shape.__init__(self, stroke = "#999", fill = "#999", z_order = 100)
+        self.start_time, self.end_time  = None, None
+        self.width, self.height = 0, 0
+        self.fixed = False
 
-class DayLine(graphics.Scene):
-    def get_value_at_pos(self, x):
-        """returns mapped value at the coordinates x,y"""
-        return x / float(self.width / self.view_minutes)
+        self.start_label = graphics.Label("", 8, "#333", visible = False)
+        self.end_label = graphics.Label("", 8, "#333", visible = False)
+        self.duration_label = graphics.Label("", 8, "#FFF", visible = False)
+
+        self.add_child(self.start_label, self.end_label, self.duration_label)
+
+    def draw_shape(self):
+        self.graphics.rectangle(0, 0, self.width, self.height - self.duration_label.height - 5.5)
+        self.graphics.fill(self.fill, 0.5)
+
+        self.graphics.rectangle(0, 0, self.width, self.height - self.duration_label.height - 5.5)
+        self.graphics.stroke(self.fill)
+
+
+        # adjust labels
+        self.start_label.visible = self.fixed == False and self.start_time is not None
+        if self.start_label.visible:
+            self.start_label.text = self.start_time.strftime("%H:%M")
+            if self.x - self.start_label.width - 5 > 0:
+                self.start_label.x = -self.start_label.width - 5
+            else:
+                self.start_label.x = 5
+
+            self.start_label.y = self.height - self.start_label.height
 
+        self.end_label.visible = self.fixed == False and self.end_time is not None
+        if self.end_label.visible:
+            self.end_label.text = self.end_time.strftime("%H:%M")
+            self.end_label.x = self.width + 5
+            self.end_label.y = self.height - self.end_label.height
 
-    #normal stuff
-    def __init__(self):
+
+
+            duration = self.end_time - self.start_time
+            duration = int(duration.seconds / 60)
+            self.duration_label.text =  "%02d:%02d" % (duration / 60, duration % 60)
+
+            self.duration_label.visible = self.duration_label.width < self.width
+            if self.duration_label.visible:
+                self.duration_label.y = (self.height - self.duration_label.height) / 2
+                self.duration_label.x = (self.width - self.duration_label.width) / 2
+        else:
+            self.duration_label.visible = False
+
+
+
+class DayLine(graphics.Scene):
+    __gsignals__ = {
+        "on-time-chosen": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
+    }
+
+    def __init__(self, start_time = None):
         graphics.Scene.__init__(self)
 
-        self.set_events(gtk.gdk.EXPOSURE_MASK
-                                 | gtk.gdk.LEAVE_NOTIFY_MASK
-                                 | gtk.gdk.BUTTON_PRESS_MASK
-                                 | gtk.gdk.BUTTON_RELEASE_MASK
-                                 | gtk.gdk.POINTER_MOTION_MASK
-                                 | gtk.gdk.POINTER_MOTION_HINT_MASK)
-        self.connect("button_release_event", self.on_button_release)
-        self.connect("motion_notify_event", self.draw_cursor)
-        self.highlight_start, self.highlight_end = None, None
-        self.drag_start = None
-        self.move_type = ""
-        self.on_time_changed = None #override this with your func to get notified when user changes date
-        self.on_more_data = None #supplement with more data func that accepts single date
-        self.in_progress = False
 
-        self.range_start = None
-        self.range_start_int = None #same date just expressed as integer so we can interpolate it  (a temporar hack)
 
-        self.in_motion = False
-        self.days = []
+        day_start = conf.get("day_start_minutes")
+        self.day_start = dt.time(day_start / 60, day_start % 60)
 
-        self.view_minutes = float(12 * 60) #how many minutes are we going to show
+        self.view_time = start_time or dt.datetime.combine(dt.date.today(), self.day_start)
+        self.start_time = self.view_time - dt.timedelta(hours=12) # we will work with twice the time we will be displaying
 
-        # TODO - get rid of these
-        # use these to mark area where the "real" drawing is going on
-        self.graph_x, self.graph_y = 0, 0
+        self.fact_bars = []
+        self.categories = []
 
         self.connect("on-enter-frame", self.on_enter_frame)
+        self.connect("on-mouse-move", self.on_mouse_move)
+        self.connect("on-mouse-down", self.on_mouse_down)
+        self.connect("on-mouse-up", self.on_mouse_up)
+        self.connect("on-click", self.on_click)
 
-    def draw(self, day_facts, highlight = None):
-        """Draw chart with given data"""
-        self.facts = day_facts
-        if self.facts:
-            self.days.append(self.facts[0]["start_time"].date())
 
-        start_time = highlight[0] - dt.timedelta(minutes = highlight[0].minute) - dt.timedelta(hours = 10)
+        self.selection = Selection()
+        self.chosen_selection = Selection()
 
-        start_time_int = int(time.mktime(start_time.timetuple()))
+        self.add_child(self.selection, self.chosen_selection)
 
-        if self.range_start:
-            self.range_start = start_time
-            self.scroll_to_range_start()
-        else:
-            self.range_start = start_time
-            self.range_start_int = start_time_int
+        self.drag_start = None
+        self.current_x = None
 
 
-        self.highlight = highlight
+    def add_facts(self, facts, highlight):
+        for fact in facts:
+            fact_bar = graphics.Rectangle(0, 0, fill = "#aaa") # dimensions will depend on screen situation
+            fact_bar.fact = fact
 
-        self.show()
+            if fact['category'] in self.categories:
+                fact_bar.category = self.categories.index(fact['category'])
+            else:
+                fact_bar.category = len(self.categories)
+                self.categories.append(fact['category'])
 
-        self.redraw()
+            self.add_child(fact_bar)
+            self.fact_bars.append(fact_bar)
 
+        self.view_time = dt.datetime.combine(facts[0]['start_time'].date(), self.day_start)
+        self.start_time = self.view_time - dt.timedelta(hours=12)
 
-    def on_button_release(self, area, event):
-        if not self.drag_start:
-            return
+        if highlight:
+            self.chosen_selection.start_time = highlight[0]
+            self.chosen_selection.end_time = highlight[1]
+            self.chosen_selection.fixed = True
 
-        self.drag_start, self.move_type = None, None
 
-        if event.state & gtk.gdk.BUTTON1_MASK:
-            self.__call_parent_time_changed()
+    def on_mouse_down(self, scene, event):
+        self.drag_start = self.current_x
+        if self.chosen_selection in self.sprites:
+            self.sprites.remove(self.chosen_selection)
 
-    def set_in_progress(self, in_progress):
-        self.in_progress = in_progress
+    def on_mouse_up(self, scene):
+        if self.drag_start:
+            self.drag_start = None
+            self.choose()
 
-    def __call_parent_time_changed(self):
-        #now calculate back from pixels into minutes
-        start_time = self.highlight[0]
-        end_time = self.highlight[1]
+    def on_click(self, scene, event, targets):
+        self.drag_start = None
+        self.emit("on-time-chosen", self.chosen_selection.start_time, None)
+        self.choose()
 
-        if self.on_time_changed:
-            self.on_time_changed(start_time, end_time)
 
-    def get_time(self, pixels):
-        minutes = self.get_value_at_pos(x = pixels)
-        return dt.datetime.fromtimestamp(self.range_start_int) + dt.timedelta(minutes = minutes)
+    def choose(self):
+        self.sprites.remove(self.selection)
 
+        self.chosen_selection = self.selection
+        self.chosen_selection.fixed = True
 
+        self.selection = Selection()
+        self.add_child(self.selection, self.chosen_selection)
 
-    def draw_cursor(self, area, event):
-        if event.is_hint:
-            x, y, state = event.window.get_pointer()
-        else:
-            x = event.x + self.graph_x
-            y = event.y + self.graph_y
-            state = event.state
-
-        mouse_down = state & gtk.gdk.BUTTON1_MASK
-
-        highlight_start, highlight_end = None, None
-        if self.highlight_start:
-            highlight_start = self.highlight_start + self.graph_x
-            highlight_end = self.highlight_end + self.graph_x
-
-        if highlight_start != None:
-            start_drag = 10 > (highlight_start - x) > -1
-
-            end_drag = 10 > (x - highlight_end) > -1
-
-            if start_drag and end_drag:
-                start_drag = abs(x - highlight_start) < abs(x - highlight_end)
-
-            in_between = highlight_start <= x <= highlight_end
-            scale = True
-
-            if self.in_progress:
-                end_drag = False
-                in_between = False
-
-            if mouse_down and not self.drag_start:
-                self.drag_start = x
-                if start_drag:
-                    self.move_type = "start"
-                elif end_drag:
-                    self.move_type = "end"
-                elif in_between:
-                    self.move_type = "move"
-                    self.drag_start = x - self.highlight_start + self.graph_x
-                elif scale:
-                    self.move_type = "scale_drag"
-                    self.drag_start_time = dt.datetime.fromtimestamp(self.range_start_int)
-
-
-            if mouse_down and self.drag_start:
-                start, end = 0, 0
-                if self.move_type and self.move_type != "scale_drag":
-                    if self.move_type == "start":
-                        if 0 <= x <= self.width:
-                            start = x - self.graph_x
-                            end = self.highlight_end
-                    elif self.move_type == "end":
-                        if 0 <= x <= self.width:
-                            start = self.highlight_start
-                            end = x - self.graph_x
-                    elif self.move_type == "move":
-                        width = self.highlight_end - self.highlight_start
-                        start = x - self.drag_start + self.graph_x
-
-                        end = start + width
-
-                    if end - start > 1:
-                        self.highlight = (self.get_time(start), self.get_time(end))
-                        self.redraw()
-
-                    self.__call_parent_time_changed()
-                else:
-                    self.range_start = self.drag_start_time + dt.timedelta(minutes = self.get_value_at_pos(self.drag_start) - self.get_value_at_pos(x))
-                    self.scroll_to_range_start()
-
-
-            if start_drag:
-                area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_SIDE))
-            elif end_drag:
-                area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.RIGHT_SIDE))
-            elif in_between:
-                area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
-            else:
-                area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.ARROW))
+        self.emit("on-time-chosen", self.chosen_selection.start_time, self.chosen_selection.end_time)
+        self.redraw()
 
+    def on_mouse_move(self, scene, event):
+        if self.current_x:
+            active_bar = None
+            # find if we are maybe on a bar
+            for bar in self.fact_bars:
+                if bar.x < self.current_x < bar.x + bar.width:
+                    active_bar = bar
+                    break
+
+            if active_bar:
+                self.set_tooltip_text("%s - %s" % (active_bar.fact['name'], active_bar.fact['category']))
+            else:
+                self.set_tooltip_text("")
 
-    def _minutes_from_start(self, date):
-            delta = (date - dt.datetime.fromtimestamp(self.range_start_int))
-            return delta.days * 24 * 60 + delta.seconds / 60
+        self.redraw()
 
-    def scroll_to_range_start(self):
-        self.tweener.kill_tweens(self)
-        self.animate(self, {"range_start_int": int(time.mktime(self.range_start.timetuple())),
-                            "tweenType": pytweener.Easing.Expo.ease_out,
-                            "tweenTime": 0.4})
 
     def on_enter_frame(self, scene, context):
         g = graphics.Graphics(context)
 
+        vertical = 7
+        minute_pixel = (24.0 * 60) / self.width
+
+        snap_points = []
 
-        self.layout = context.create_layout()
-        default_font = pango.FontDescription(gtk.Style().font_desc.to_string())
-        default_font.set_size(pango.SCALE * 8)
-        self.layout.set_font_description(default_font)
+        g.set_line_style(width=1)
 
-        # check if maybe we are approaching day boundaries and should ask for
-        # more data!
-        now = dt.datetime.fromtimestamp(self.range_start_int)
-        if self.on_more_data:
-            date_plus = (now + dt.timedelta(hours = 12 + 2*4 + 1)).date()
-            date_minus = (now - dt.timedelta(hours=1)).date()
 
-            if date_minus != now.date() and date_minus not in self.days:
-                self.facts += self.on_more_data(date_minus)
-                self.days.append(date_minus)
-            elif date_plus != now.date() and date_plus not in self.days:
-                self.facts += self.on_more_data(date_plus)
-                self.days.append(date_plus)
 
+        for bar in self.fact_bars:
+            bar.y = vertical * bar.category
+            bar.height = vertical
 
-        #TODO - use system colors and fonts
 
-        g.set_line_style(width=1)
+            minutes = (bar.fact['start_time'] - self.view_time).seconds / 60 + (bar.fact['start_time'] - self.view_time).days * 24  * 60
+
+            bar.x = round(minutes / minute_pixel) + 0.5
+            bar.width = round((bar.fact['delta']).seconds / 60 / minute_pixel)
 
-        #we will buffer 4 hours to both sides so partial labels also appear
-        range_end = now + dt.timedelta(hours = 12 + 2 * 4)
-        self.graph_x = -self.width / 3 #so x moves one third out of screen
+            snap_points.append(bar.x)
+            snap_points.append(bar.x + bar.width)
 
-        pixels_in_minute = self.width / self.view_minutes
 
-        minutes = self._minutes_from_start(range_end)
+        if self.view_time < dt.datetime.now() < self.view_time + dt.timedelta(hours = 24):
+            minutes = round((dt.datetime.now() - self.view_time).seconds / 60 / minute_pixel) + 0.5
+            g.move_to(minutes, 0)
+            g.line_to(minutes, 0 + vertical * 10)
+            g.stroke("#f00", 0.4)
+            snap_points.append(minutes - 0.5)
 
+        if self.chosen_selection.end_time and not self.chosen_selection.width:
+            # we have time but no pixels
+            minutes = round((self.chosen_selection.start_time - self.view_time).seconds / 60 / minute_pixel) + 0.5
+            self.chosen_selection.x = minutes
+            self.chosen_selection.width = round((self.chosen_selection.end_time - self.chosen_selection.start_time).seconds / 60 / minute_pixel)
+            self.chosen_selection.height = self.height
 
-        graph_y = 4
-        graph_height = self.height - 10
-        graph_y2 = graph_y + graph_height
+            # use the oportunity to set proper colors too
+            self.chosen_selection.fill = self.get_style().bg[gtk.STATE_SELECTED].to_string()
+            self.chosen_selection.duration_label.color = self.get_style().fg[gtk.STATE_SELECTED].to_string()
 
 
-        # graph area
-        g.fill_area(0, graph_y - 1, self.width, graph_height, (1,1,1))
+        self.selection.visible = self.mouse_x is not None
 
-        context.save()
-        context.translate(self.graph_x, self.graph_y)
+        if self.mouse_x:
+            start_x = max(min(self.mouse_x, self.width-1), 0) #mouse, but within screen regions
 
-        #bars
-        for fact in self.facts:
-            start_minutes = self._minutes_from_start(fact["start_time"])
+            # check for snap points
+            delta, closest_snap = min((abs(start_x - i), i) for i in snap_points)
 
-            if fact["end_time"]:
-                end_minutes = self._minutes_from_start(fact["end_time"])
+
+            if abs(closest_snap - start_x) < 5 and (not self.drag_start or self.drag_start != closest_snap):
+                start_x = closest_snap
+                minutes = int(start_x * minute_pixel)
             else:
-                if fact["start_time"].date() > dt.date.today() - dt.timedelta(days=1):
-                    end_minutes = self._minutes_from_start(dt.datetime.now())
-                else:
-                    end_minutes = start_minutes
-
-            if end_minutes * pixels_in_minute > 0 and \
-                start_minutes * pixels_in_minute + self.graph_x < self.width:
-                    g.set_color((0.86, 0.86, 0.86), 0.5)
-
-                    g.rectangle(round(start_minutes * pixels_in_minute),
-                                      graph_y,
-                                      round(end_minutes * pixels_in_minute - start_minutes * pixels_in_minute),
-                                      graph_height - 1)
-                    g.fill()
-                    g.stroke()
-
-                    g.set_color((0.86, 0.86, 0.86), 1)
-                    g.move_to(round(start_minutes * pixels_in_minute) + 0.5, graph_y)
-                    g.line_to(round(start_minutes * pixels_in_minute) + 0.5, graph_y2)
-                    g.move_to(round(end_minutes * pixels_in_minute) + 0.5, graph_y)
-                    g.line_to(round(end_minutes * pixels_in_minute) + 0.5, graph_y2)
-                    g.stroke()
-
-
-
-        #time scale
-        g.set_color("#000")
-        self.layout.set_width(-1)
-        for i in range(minutes):
-            label_time = (now + dt.timedelta(minutes=i))
-
-            if label_time.minute == 0:
-                g.set_color((0.8, 0.8, 0.8))
-                g.move_to(round(i * pixels_in_minute) + 0.5, graph_y2 - 15)
-                g.line_to(round(i * pixels_in_minute) + 0.5, graph_y2)
-                g.stroke()
-            elif label_time.minute % 15 == 0:
-                g.set_color((0.8, 0.8, 0.8))
-                g.move_to(round(i * pixels_in_minute) + 0.5, graph_y2 - 5)
-                g.line_to(round(i * pixels_in_minute) + 0.5, graph_y2)
-                g.stroke()
-
-
-
-            if label_time.minute == 0 and label_time.hour % 2 == 0:
-                if label_time.hour == 0:
-                    g.set_color((0.8, 0.8, 0.8))
-                    g.move_to(round(i * pixels_in_minute) + 0.5, graph_y)
-                    g.line_to(round(i * pixels_in_minute) + 0.5, graph_y2)
-                    label_minutes = label_time.strftime("%b %d")
-                else:
-                    label_minutes = label_time.strftime("%H<small><sup>%M</sup></small>")
-
-                g.set_color((0.4, 0.4, 0.4))
-                self.layout.set_markup(label_minutes)
-                label_w, label_h = self.layout.get_pixel_size()
-
-                g.move_to(round(i * pixels_in_minute) + 2, graph_y2 - label_h - 8)
-
-                context.show_layout(self.layout)
-        g.stroke()
-
-        #highlight rectangle
-        if self.highlight:
-            self.highlight_start = round(self._minutes_from_start(self.highlight[0]) * pixels_in_minute)
-            self.highlight_end = round(self._minutes_from_start(self.highlight[1]) * pixels_in_minute)
-
-        #TODO - make a proper range check here
-        if self.highlight_end + self.graph_x > 0 and self.highlight_start + self.graph_x < self.width:
-            rgb = colorsys.hls_to_rgb(.6, .7, .5)
-
-            g.fill_area(self.highlight_start,
-                           graph_y,
-                           self.highlight_end - self.highlight_start,
-                           graph_height,
-                           (rgb[0], rgb[1], rgb[2], 0.5))
-            g.stroke()
-
-            g.set_color(rgb)
-            g.move_to(self.highlight_start + 0.5, graph_y)
-            g.line_to(self.highlight_start + 0.5, graph_y + graph_height)
-            g.move_to(self.highlight_end + 0.5, graph_y)
-            g.line_to(self.highlight_end + 0.5, graph_y + graph_height)
-            g.stroke()
-
-        context.restore()
-
-        #and now put a frame around the whole thing
-        g.set_color((0.7, 0.7, 0.7))
-        g.rectangle(0, graph_y-0.5, self.width - 0.5, graph_height)
-        g.stroke()
-
-        if self.move_type == "move" and (self.highlight_start + self.graph_x <= 0 or self.highlight_end + self.graph_x >= self.width):
-            if self.highlight_start + self.graph_x <= 0:
-                self.range_start = self.range_start - dt.timedelta(minutes=30)
-            if self.highlight_end + self.graph_x >= self.width:
-                self.range_start = self.range_start + dt.timedelta(minutes=30)
-
-            self.scroll_to_range_start()
+                start_x = start_x + 0.5
+                minutes = int(round(start_x * minute_pixel / 15)) * 15
+
+
+            self.current_x = minutes / minute_pixel
+
+
+            start_time = self.view_time + dt.timedelta(hours = minutes / 60, minutes = minutes % 60)
+
+            end_time, end_x = None, None
+            if self.drag_start:
+                minutes = int(self.drag_start * minute_pixel)
+                end_time =  self.view_time + dt.timedelta(hours = minutes / 60, minutes = minutes % 60)
+                end_x = round(self.drag_start) + 0.5
+
+            if end_time and end_time < start_time:
+                start_time, end_time = end_time, start_time
+                start_x, end_x = end_x, start_x
+
+
+            self.selection.start_time = start_time
+            self.selection.end_time = end_time
+
+            self.selection.x = start_x
+            self.selection.width = 0
+            if end_time:
+                self.selection.width = end_x - start_x
+
+            self.selection.y = 0
+            self.selection.height = self.height
+
+            self.selection.fill = self.get_style().bg[gtk.STATE_SELECTED].to_string()
+            self.selection.duration_label.color = self.get_style().fg[gtk.STATE_SELECTED].to_string()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]