bigboard r7387 - in trunk/bigboard: . stocks/people



Author: otaylor
Date: Thu Jun 19 03:33:22 2008
New Revision: 7387
URL: http://svn.gnome.org/viewvc/bigboard?rev=7387&view=rev

Log:
scroll_ribbon.py: add scroll_range_visible() to allow scrolling a range
 of pixels visible. (Probably should be scroll_item_visible() taking 
 any descendant item, but don't want to figure out the complexities of
 coordinate translation at the moment.)

PeopleStock.py: Make the action of hitting return for a person in the 
 search result open up the slideout for the person rather than opening
 the (likely non-existent) Mugshot home page.


Modified:
   trunk/bigboard/scroll_ribbon.py
   trunk/bigboard/stocks/people/PeopleStock.py

Modified: trunk/bigboard/scroll_ribbon.py
==============================================================================
--- trunk/bigboard/scroll_ribbon.py	(original)
+++ trunk/bigboard/scroll_ribbon.py	Thu Jun 19 03:33:22 2008
@@ -39,14 +39,49 @@
         gobject.GObject.__init__(self)
         self.__box = None
 
-        self.__offset = 0
+        self.offset = 0
 
         self.viewport = gtk.gdk.Rectangle(0, 0, 0, 0)
 
-    def scroll_by(self, increment):
-        self.__offset = self.__offset + increment
+    def scroll_to(self, offset):
+        self.offset = offset
         self.__box.emit_request_changed()
 
+    def scroll_by(self, increment):
+        self.scroll_to(self.offset + increment)
+
+    def scroll_range_visible(self, y, height):
+        new_offset = self.offset
+        
+        # We need to handle the case the case where the scrolling from the top
+        # position adds a scroll button; we do this by calculating the position
+        # assuming both scroll buttons
+
+        box_width, box_height = self.__box.get_allocation()
+        (_, up_natural) = self.__get_height_request(self.__up_button, box_width)
+        (_, down_natural) = self.__get_height_request(self.__down_button, box_width)
+        
+        if y + self.offset < 0:
+            new_offset = - y
+        elif y + height + self.offset > self.viewport.height:
+            viewport_height = box_height - up_natural - down_natural
+            new_offset = - (y + height - viewport_height)
+
+        if new_offset != self.offset:
+            fixup = new_offset - self.offset
+
+            # If we are adding or removing the scroll area, that will also
+            # affect how much we move the item from
+            if self.offset == 0 and new_offset != 0:
+                fixup += up_natural
+            elif self.offset != 0 and new_offset == 0:
+                fixup -= up_natural
+            
+            self.scroll_to(new_offset)
+            return fixup
+        else:
+            return 0
+
     def __on_up_clicked(self, button):
         self.scroll_by(max(self.viewport.height - 5, self.__box.increment))
 
@@ -175,20 +210,20 @@
         # max offset has top of child aligned with top of viewport
         max_offset = 0
             
-        offset = max(self.__offset, min_offset)
+        offset = max(self.offset, min_offset)
         offset = min(offset, max_offset)
 
         ## save this new offset
-        self.__offset = offset
+        self.offset = offset
 
         ## nuke the top button if needed
-        if self.__offset == 0:
+        if self.offset == 0:
             self.viewport.height = self.viewport.height + up_natural
             self.viewport.y = self.viewport.y - up_natural
             up_natural = 0
 
         ## nuke the bottom button if needed
-        if self.__offset == min_offset:
+        if self.offset == min_offset:
             self.viewport.height = self.viewport.height + down_natural
             down_natural = 0
 
@@ -207,7 +242,7 @@
             # we always allocate the child its full height; then we 
             # don't draw the parts outside the viewport
             contents_child.x = 0
-            contents_child.y = self.viewport.y + self.__offset
+            contents_child.y = self.viewport.y + self.offset
             contents_child.allocate(contents_child.x, contents_child.y, width,
                                     child_natural, origin_changed)
 
@@ -225,8 +260,6 @@
     def __init__(self, **kwargs):
         hippo.CanvasBox.__init__(self, **kwargs)
 
-        self.__offset = 0
-
         self.__layout = ScrollRibbonLayout()
         self.set_layout(self.__layout)
 
@@ -238,6 +271,21 @@
     def set_increment(self, inc):
         self.increment = inc
 
+    def scroll_range_visible(self, y, height):
+        """Scroll the box to make a range of pixel positions visible
+
+        Adjusts the scroll position of the box so that the range y to y + height
+        is visible. The pixel positions are relative to the item that is used
+        as the content of the box.
+
+        The operation is asynchronous. Returns the number of pixels that the
+        contents of the box will be shifted when the asynchronous operation
+        occurs.
+
+        """
+        
+        return self.__layout.scroll_range_visible(y, height)
+
     def do_scroll_event(self, event):
         if event.direction == hippo.SCROLL_UP:
             self.__layout.scroll_by(self.increment)

Modified: trunk/bigboard/stocks/people/PeopleStock.py
==============================================================================
--- trunk/bigboard/stocks/people/PeopleStock.py	(original)
+++ trunk/bigboard/stocks/people/PeopleStock.py	Thu Jun 19 03:33:22 2008
@@ -38,7 +38,7 @@
         self.__person_items = {}
 
         self.__slideout = None
-        self.__slideout_item = None
+        self.__current_slideout = None
         self.__last_slideout_event_time = None
         self.__in_slideout_close_event = False
 
@@ -54,7 +54,7 @@
             
         ## add a new search provider (FIXME never gets disabled)
         search.enable_search_provider('people',
-                                      lambda: PeopleSearchProvider(self.__tracker))
+                                      lambda: PeopleSearchProvider(self.__tracker, self))
 
         imclient.get_default().connect(
                 'notify::configured', self.__on_imclient_configured_changed)
@@ -135,17 +135,21 @@
     def __handle_item_pressed(self, item, event):
         self.__in_slideout_close_event = self.__last_slideout_event_time == gtk.get_current_event_time()
         
-    def __handle_item_activated(self, item):
-        same_item = self.__slideout_item == item
+    def __slideout_item(self, item, y_fixup=0):
+        # y_fixup is a number to be added to the the current position of the item
+        # to determine where it will be after asynchronous scrolling occurs
+        same_item = self.__current_slideout == item
         if same_item and self.__in_slideout_close_event:
-            self.__slideout_item = None  
+            self.__current_slideout = None  
             self.__in_slideout_close_event = False
             return True
 
         self.__in_slideout_close_event = False
 
         self.__slideout = bigboard.slideout.Slideout()
-        self.__slideout_item = item
+        self.__current_slideout = item
+        item_x, item_y = item.get_screen_coords()
+        
         coords = item.get_screen_coords()
 
         p = ProfileItem(item.get_person(),
@@ -156,13 +160,36 @@
         self.__slideout.connect("close", self.__close_slideout)
         try:
             success = False
-            success = self.__slideout.slideout_from(coords[0] + item.get_allocation()[0] + 4, coords[1])
+            success = self.__slideout.slideout_from(item_x + item.get_allocation()[0] + 4, item_y + y_fixup)
         finally:
             if not success:
                 self.__close_slideout()
 
         return success
 
+    def __handle_item_activated(self, item):
+        self.__slideout_item(item)
+
+    def slideout_person(self, person):
+        try:
+            item = self.__person_items[person]
+        except KeyError:
+            return
+
+        # Compute the position of the item relative to it's parent item; a bit
+        # hacky, but I can't think of an easier way to do it
+        _, box_y = self.__person_box.get_context().translate_to_widget(self.__person_box)
+        _, item_y = item.get_context().translate_to_widget(item)
+        box_relative_y = item_y - box_y
+
+        # Now scroll the scroll ribbon so that the item is visible; since this
+        # is asynchronous, we get a "fixup" indicating the number of pixels that
+        # the item will eventually move
+        _, item_height = item.get_allocation()
+        y_fixup = self.__scroll_box.scroll_range_visible(box_relative_y, item_height)
+        
+        self.__slideout_item(item, y_fixup)
+
     def __on_more_button(self):
         if self.__people_browser is None:
             self.__people_browser = peoplebrowser.PeopleBrowser(self)
@@ -199,21 +226,17 @@
 
     def _on_activated(self):
         """Action when user has activated the result"""
-        if self.__person.user:
-            libbig.show_url(self.__person.user.homeUrl)
-        else:
-            ### FIXME - what should we do here? open an IM conversation?
-            ### or scroll to and pop out the user in the people stock?
-            pass
+        self.get_provider().get_stock().slideout_person(self.__person)
 
 class PeopleSearchProvider(search.SearchProvider):    
-    def __init__(self, tracker):
+    def __init__(self, tracker, stock):
         super(PeopleSearchProvider, self).__init__()
         self.__tracker = tracker
+        self.__stock = stock
 
     def get_heading(self):
         return "People"
-        
+
     def perform_search(self, query, consumer):
         results = []
         
@@ -241,3 +264,7 @@
 
         if len(results) > 0:
             consumer.add_results(results)
+
+    def get_stock(self):
+        return self.__stock
+        



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