diff browser_side/panels.py @ 85:a8f027738c16

browser side: widgets cells can now be added by putting a widget on a border
author Goffi <goffi@goffi.org>
date Mon, 27 Jun 2011 03:14:37 +0200
parents 8f35e9970e7f
children 6c3b3254605f
line wrap: on
line diff
--- a/browser_side/panels.py	Sun Jun 26 23:23:22 2011 +0200
+++ b/browser_side/panels.py	Mon Jun 27 03:14:37 2011 +0200
@@ -53,8 +53,9 @@
 class DropCell(DropWidget):
     """Cell in the middle grid which replace itself with the dropped widget on DnD"""
     
-    def __init__(self):
+    def __init__(self, host):
         DropWidget.__init__(self)
+        self.host = host
         self.setStyleName('dropCell')
     
     def onDragEnter(self, event):
@@ -112,19 +113,18 @@
             self.host.unregisterWidget(self)
             if not isinstance(_new_panel, LiberviaWidget):
                 print ('WARNING: droping an object which is not a class of LiberviaWidget')
-        grid = self.getParent()
-        row_idx, cell_idx = self._getCellAndRow(grid, event)
+        _flextable = self.getParent()
+        _widgetpanel = _flextable.getParent()
+        row_idx, cell_idx = self._getCellAndRow(_flextable, event)
         if self.host.selected == self:
             self.host.select(None)
-        self.removeFromParent()
-        grid.setWidget(row_idx, cell_idx, _new_panel)
-        _panels = list(grid) #this suppose that we only use 1 row, need to be changed in the futur
-        _unempty_panels = filter(lambda wid:not isinstance(wid,EmptyPanel),list(grid))
+        _widgetpanel.changeWidget(row_idx, cell_idx, _new_panel)
+        """_unempty_panels = filter(lambda wid:not isinstance(wid,EmptyWidget),list(_flextable))
         _width = 90/float(len(_unempty_panels) or 1)
         #now we resize all the cell of the column
         for panel in _unempty_panels:
             td_elt = panel.getElement().parentNode
-            DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width)
+            DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width)"""
         #FIXME: delete object ? Check the right way with pyjamas
 
 class LiberviaWidget(DropCell, VerticalPanel, ClickHandler):
@@ -136,9 +136,8 @@
         @param title: title show in the header of the widget
         @param selectable: True is widget can be selected by user"""
         VerticalPanel.__init__(self)
-        DropCell.__init__(self)
+        DropCell.__init__(self, host)
         ClickHandler.__init__(self)
-        self.host = host
         self.__selectable = selectable
         self.__title_id = HTMLPanel.createUniqueId()
         self.__setting_button_id = HTMLPanel.createUniqueId()
@@ -233,16 +232,35 @@
     def scrollToBottom(self):
         self.setScrollPosition(self.spanel.getElement().scrollHeight)
 
-class EmptyPanel(DropCell, SimplePanel):
+class EmptyWidget(DropCell, SimplePanel):
     """Empty dropable panel"""
 
     def __init__(self, host):
         SimplePanel.__init__(self)
-        self.host = host
+        DropCell.__init__(self, host)
+        self.setWidget(HTML('&nbsp;'))
         self.setSize('100%','100%')
-        DropCell.__init__(self)
-        self.setWidget(HTML('&nbsp;'))
-    
+
+class BorderWidget(EmptyWidget):
+    def __init__(self, host):
+        EmptyWidget.__init__(self, host)
+        self.addStyleName('borderPanel')
+
+class LeftBorderWidget(BorderWidget):
+    def __init__(self, host):
+        BorderWidget.__init__(self, host)
+        self.addStyleName('leftBorderWidget')
+
+class RightBorderWidget(BorderWidget):
+    def __init__(self, host):
+        BorderWidget.__init__(self, host)
+        self.addStyleName('rightBorderWidget')
+
+class BottomBorderWidget(BorderWidget):
+    def __init__(self, host):
+        BorderWidget.__init__(self, host)
+        self.addStyleName('bottomBorderWidget')
+
 class UniBoxPanel(SimplePanel):
     """Panel containing the UniBox"""
 
@@ -618,22 +636,83 @@
 
 class WidgetsPanel(SimplePanel):
     
-    def __init__(self):
+    def __init__(self, host):
         SimplePanel.__init__(self)
+        self.host = host
         self.flextable = FlexTable()
         self.flextable.setSize('100%','100%')
         self.add(self.flextable)
         self.setStyleName('widgetsPanel')
+        _bottom = BottomBorderWidget(self.host)
+        self.flextable.setWidget(0, 0, _bottom) #There will be always an Empty widget on the last row,
+                                                                      #dropping a widget there will add a new row
+        self._max_cols = 1 #give the maximum number of columns i a raw
 
-    def addWidget(self, wid):
-        """Add a widget to a new cell"""
-        row = max(0, self.flextable.getRowCount()-1)
+    def changeWidget(self, row, col, wid):
+        """Change the widget in the given location, add row or columns when necessary"""
+        print "changing widget:", wid, row, col
+        last_row = max(0, self.flextable.getRowCount()-1)
         try:
-            col = self.flextable.getCellCount(0)
-        except AttributeError:
-            col = 0
-        print "putting widget %s at %d, %d" % (wid, row, col)
-        self.flextable.setWidget(row, col, wid) 
+            prev_wid = self.flextable.getWidget(row, col)
+        except:
+            print "ERROR: Trying to change an unexisting widget !"
+            return
+
+        cellFormatter = self.flextable.getFlexCellFormatter()
+
+        if isinstance(prev_wid, BorderWidget):
+            #We are on a border, we must create a row and/or columns
+            print "BORDER WIDGET"
+            prev_wid.removeStyleName('dragover')
+            
+            if isinstance(prev_wid, BottomBorderWidget):
+                #We are on the bottom border, we create a new row
+                self.flextable.insertRow(last_row)
+                self.flextable.setWidget(last_row, 0, LeftBorderWidget(self.host))
+                self.flextable.setWidget(last_row, 1, wid)
+                self.flextable.setWidget(last_row, 2, RightBorderWidget(self.host))
+                cellFormatter.setHorizontalAlignment(last_row, 2, HasAlignment.ALIGN_RIGHT)
+                row = last_row
+                last_row+=1
+
+            elif isinstance(prev_wid, LeftBorderWidget):
+                if col!=0:
+                    print "ERROR: LeftBorderWidget must be on the first column !"
+                    return
+                self.flextable.insertCell(row, col+1)
+                self.flextable.setWidget(row, 1, wid)
+
+            elif isinstance(prev_wid, RightBorderWidget):
+                if col!=self.flextable.getCellCount(row)-1:
+                    print "ERROR: RightBorderWidget must be on the last column !"
+                    return
+                self.flextable.insertCell(row, col)
+                self.flextable.setWidget(row, col, wid)
+
+        else:
+            prev_wid.removeFromParent()
+            self.flextable.setWidget(row, col, wid)
+        
+        _max_cols = max(self._max_cols, self.flextable.getCellCount(row))
+        if _max_cols != self._max_cols:
+            #we hage to adjust sizes
+            self._max_cols = _max_cols
+            width = 100.0/max(1, self._max_cols-2) #we don't count the borders
+            for row_idx in range(self.flextable.getRowCount()):
+                for col_idx in range(self.flextable.getCellCount(row_idx)):
+                    _widget = self.flextable.getWidget(row_idx, col_idx)
+                    if not isinstance(_widget, BorderWidget):
+                        td_elt = _widget.getElement().parentNode
+                        DOM.setStyleAttribute(td_elt, "width", "%.2f%%" % width)
+
+            cellFormatter.setColSpan(last_row, 0, self._max_cols)
+
+    
+    def addWidget(self, wid):
+        """Add a widget to a new cell on the next to last row"""
+        last_row = max(0, self.flextable.getRowCount()-1)
+        print "putting widget %s at %d, %d" % (wid, last_row, 0)
+        self.changeWidget(last_row, 0, wid)
 
 class MainDiscussionPanel(HorizontalPanel):
     
@@ -641,13 +720,11 @@
         self.host=host
         HorizontalPanel.__init__(self)
         self._left = self.host.contact_panel
-        self._right = WidgetsPanel()
+        self._right = WidgetsPanel(host)
         self._right.setWidth('100%')
         self._right.setHeight('100%')
         self.add(self._left)
-        #self.setCellWidth(self._left, "15%")
         self.add(self._right)
-        #self.setCellWidth(self._right, "85%")
         self.setCellWidth(self._right, "100%")
     
     def addWidget(self, wid):
@@ -655,11 +732,6 @@
         print "main addWidget", wid
         self._right.addWidget(wid)
 
-    def changePanel(self, idx, panel):
-        pass
-        #self._right.setWidget(0,idx,panel)
-        #self._right.getCellFormatter().setWidth(0, idx, '5%' if isinstance(panel, EmptyPanel) else '90%')
-
 class MainTabPanel(TabPanel):
 
     def __init__(self, host):