Merge lp:~stephen-j-boddy/terminator/feature-redistribute-terms into lp:terminator/trunk

Proposed by Stephen Boddy
Status: Merged
Merged at revision: 1313
Proposed branch: lp:~stephen-j-boddy/terminator/feature-redistribute-terms
Merge into: lp:terminator/trunk
Diff against target: 112 lines (+88/-0)
1 file modified
terminatorlib/paned.py (+88/-0)
To merge this branch: bzr merge lp:~stephen-j-boddy/terminator/feature-redistribute-terms
Reviewer Review Type Date Requested Status
Chris Jones (community) Approve
Review via email: mp+111925@code.launchpad.net

Description of the change

Double click on a splitter evenly redistributes columns/rows in that grouping
Use the Shift modifier to redistribute lower level groupings
Use the Super modifier to redistribute higher level groupings
Use both modifiers to redistribute all groupings

Extra info:
OK, For anyone who wants to know why GTK splitters are a pain in the backside, this code will illustrate. In GTK a splitter can only have two children. This means you have to come up with tortuous code like in this commit. Oh, for a splitter like in Qt, where a splitter has as many children as you wish!

To post a comment you must log in.
Revision history for this message
Stephen Boddy (stephen-j-boddy) wrote :

Found some oddness with redistribute. I suspect bugfix-lp-1017230, rev 1311. Until I fix it please hold off on:
- feature-redistribute-terms
- bugfix-lp-1017230

1311. By Stephen Boddy

I think this fixes most of the strangeness with the clicked splitter not moving properly, but I think it can still be triggered occasionally. I'm stumped.

Revision history for this message
Stephen Boddy (stephen-j-boddy) wrote :

I think this is mostly good to go now. The oddness is mostly gone with lp:~stephen-j-boddy/terminator/feature-redistribute-terms rev 1311.

Revision history for this message
Chris Jones (cmsj) wrote :

Looks good, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'terminatorlib/paned.py'
--- terminatorlib/paned.py 2012-04-04 15:48:29 +0000
+++ terminatorlib/paned.py 2012-06-27 15:02:18 +0000
@@ -113,6 +113,92 @@
113 except TypeError:113 except TypeError:
114 err('Paned::add: %s has no signal resize-term' % widget)114 err('Paned::add: %s has no signal resize-term' % widget)
115115
116 def on_button_press(self, widget, event):
117 """Handle button presses on a Pane"""
118 if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
119 if event.state & gtk.gdk.MOD4_MASK == gtk.gdk.MOD4_MASK:
120 recurse_up=True
121 else:
122 recurse_up=False
123
124 if event.state & gtk.gdk.SHIFT_MASK == gtk.gdk.SHIFT_MASK:
125 recurse_down=True
126 else:
127 recurse_down=False
128
129 # FIXME: These idle events are creating a lot of weird issues
130 for i in range(3):
131 while gtk.events_pending():
132 gtk.main_iteration_do(False)
133 self.do_redistribute(recurse_up, recurse_down)
134
135 return True
136 else:
137 return False
138
139 def do_redistribute(self, recurse_up=False, recurse_down=False):
140 """Evenly divide available space between sibling panes"""
141 #1 Find highest ancestor of the same type => ha
142 highest_ancestor = self
143 while type(highest_ancestor.get_parent()) == type(highest_ancestor):
144 highest_ancestor = highest_ancestor.get_parent()
145
146 # (1b) If Super modifier, redistribute higher sections too
147 if recurse_up:
148 grandfather=highest_ancestor.get_parent()
149 if grandfather != self.get_toplevel():
150 grandfather.do_redistribute(recurse_up, recurse_down)
151
152 gobject.idle_add(highest_ancestor._do_redistribute, recurse_up, recurse_down)
153 while gtk.events_pending():
154 gtk.main_iteration_do(False)
155 gobject.idle_add(highest_ancestor._do_redistribute, recurse_up, recurse_down)
156
157 def _do_redistribute(self, recurse_up=False, recurse_down=False):
158 maker = Factory()
159 #2 Make a list of self + all children of same type
160 tree = [self, [], 0, None]
161 toproc = [tree]
162 number_splits = 1
163 while toproc:
164 curr = toproc.pop(0)
165 for child in curr[0].get_children():
166 if type(child) == type(curr[0]):
167 childset = [child, [], 0, curr]
168 curr[1].append(childset)
169 toproc.append(childset)
170 number_splits = number_splits+1
171 else:
172 curr[1].append([None,[], 1, None])
173 p = curr
174 while p:
175 p[2] = p[2] + 1
176 p = p[3]
177 # (1c) If Shift modifier, redistribute lower sections too
178 if recurse_down and \
179 (maker.isinstance(child, 'VPaned') or \
180 maker.isinstance(child, 'HPaned')):
181 gobject.idle_add(child.do_redistribute, False, True)
182
183 #3 Get ancestor x/y => a, and handle size => hs
184 avail_pixels=self.get_length()
185 handle_size = self.style_get_property('handle-size')
186 #4 Math! eek (a - (n * hs)) / (n + 1) = single size => s
187 single_size = (avail_pixels - (number_splits * handle_size)) / (number_splits + 1)
188 arr_sizes = [single_size]*(number_splits+1)
189 for i in range(avail_pixels % (number_splits + 1)):
190 arr_sizes[i] = arr_sizes[i] + 1
191 #5 Descend down setting the handle position to s
192 # (Has to handle nesting properly)
193 toproc = [tree]
194 while toproc:
195 curr = toproc.pop(0)
196 for child in curr[1]:
197 toproc.append(child)
198 if curr[1].index(child) == 0:
199 curr[0].set_position((child[2]*single_size)+((child[2]-1)*handle_size))
200 gobject.idle_add(curr[0].set_position, child[2]*single_size)
201
116 def remove(self, widget):202 def remove(self, widget):
117 """Remove a widget from the container"""203 """Remove a widget from the container"""
118 gtk.Paned.remove(self, widget)204 gtk.Paned.remove(self, widget)
@@ -288,6 +374,7 @@
288 Paned.__init__(self)374 Paned.__init__(self)
289 gtk.HPaned.__init__(self)375 gtk.HPaned.__init__(self)
290 self.register_signals(HPaned)376 self.register_signals(HPaned)
377 self.cnxids.new(self, 'button-press-event', self.on_button_press)
291378
292 def get_length(self):379 def get_length(self):
293 return(self.allocation.width)380 return(self.allocation.width)
@@ -302,6 +389,7 @@
302 Paned.__init__(self)389 Paned.__init__(self)
303 gtk.VPaned.__init__(self)390 gtk.VPaned.__init__(self)
304 self.register_signals(VPaned)391 self.register_signals(VPaned)
392 self.cnxids.new(self, 'button-press-event', self.on_button_press)
305393
306 def get_length(self):394 def get_length(self):
307 return(self.allocation.height)395 return(self.allocation.height)