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
1=== modified file 'terminatorlib/paned.py'
2--- terminatorlib/paned.py 2012-04-04 15:48:29 +0000
3+++ terminatorlib/paned.py 2012-06-27 15:02:18 +0000
4@@ -113,6 +113,92 @@
5 except TypeError:
6 err('Paned::add: %s has no signal resize-term' % widget)
7
8+ def on_button_press(self, widget, event):
9+ """Handle button presses on a Pane"""
10+ if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
11+ if event.state & gtk.gdk.MOD4_MASK == gtk.gdk.MOD4_MASK:
12+ recurse_up=True
13+ else:
14+ recurse_up=False
15+
16+ if event.state & gtk.gdk.SHIFT_MASK == gtk.gdk.SHIFT_MASK:
17+ recurse_down=True
18+ else:
19+ recurse_down=False
20+
21+ # FIXME: These idle events are creating a lot of weird issues
22+ for i in range(3):
23+ while gtk.events_pending():
24+ gtk.main_iteration_do(False)
25+ self.do_redistribute(recurse_up, recurse_down)
26+
27+ return True
28+ else:
29+ return False
30+
31+ def do_redistribute(self, recurse_up=False, recurse_down=False):
32+ """Evenly divide available space between sibling panes"""
33+ #1 Find highest ancestor of the same type => ha
34+ highest_ancestor = self
35+ while type(highest_ancestor.get_parent()) == type(highest_ancestor):
36+ highest_ancestor = highest_ancestor.get_parent()
37+
38+ # (1b) If Super modifier, redistribute higher sections too
39+ if recurse_up:
40+ grandfather=highest_ancestor.get_parent()
41+ if grandfather != self.get_toplevel():
42+ grandfather.do_redistribute(recurse_up, recurse_down)
43+
44+ gobject.idle_add(highest_ancestor._do_redistribute, recurse_up, recurse_down)
45+ while gtk.events_pending():
46+ gtk.main_iteration_do(False)
47+ gobject.idle_add(highest_ancestor._do_redistribute, recurse_up, recurse_down)
48+
49+ def _do_redistribute(self, recurse_up=False, recurse_down=False):
50+ maker = Factory()
51+ #2 Make a list of self + all children of same type
52+ tree = [self, [], 0, None]
53+ toproc = [tree]
54+ number_splits = 1
55+ while toproc:
56+ curr = toproc.pop(0)
57+ for child in curr[0].get_children():
58+ if type(child) == type(curr[0]):
59+ childset = [child, [], 0, curr]
60+ curr[1].append(childset)
61+ toproc.append(childset)
62+ number_splits = number_splits+1
63+ else:
64+ curr[1].append([None,[], 1, None])
65+ p = curr
66+ while p:
67+ p[2] = p[2] + 1
68+ p = p[3]
69+ # (1c) If Shift modifier, redistribute lower sections too
70+ if recurse_down and \
71+ (maker.isinstance(child, 'VPaned') or \
72+ maker.isinstance(child, 'HPaned')):
73+ gobject.idle_add(child.do_redistribute, False, True)
74+
75+ #3 Get ancestor x/y => a, and handle size => hs
76+ avail_pixels=self.get_length()
77+ handle_size = self.style_get_property('handle-size')
78+ #4 Math! eek (a - (n * hs)) / (n + 1) = single size => s
79+ single_size = (avail_pixels - (number_splits * handle_size)) / (number_splits + 1)
80+ arr_sizes = [single_size]*(number_splits+1)
81+ for i in range(avail_pixels % (number_splits + 1)):
82+ arr_sizes[i] = arr_sizes[i] + 1
83+ #5 Descend down setting the handle position to s
84+ # (Has to handle nesting properly)
85+ toproc = [tree]
86+ while toproc:
87+ curr = toproc.pop(0)
88+ for child in curr[1]:
89+ toproc.append(child)
90+ if curr[1].index(child) == 0:
91+ curr[0].set_position((child[2]*single_size)+((child[2]-1)*handle_size))
92+ gobject.idle_add(curr[0].set_position, child[2]*single_size)
93+
94 def remove(self, widget):
95 """Remove a widget from the container"""
96 gtk.Paned.remove(self, widget)
97@@ -288,6 +374,7 @@
98 Paned.__init__(self)
99 gtk.HPaned.__init__(self)
100 self.register_signals(HPaned)
101+ self.cnxids.new(self, 'button-press-event', self.on_button_press)
102
103 def get_length(self):
104 return(self.allocation.width)
105@@ -302,6 +389,7 @@
106 Paned.__init__(self)
107 gtk.VPaned.__init__(self)
108 self.register_signals(VPaned)
109+ self.cnxids.new(self, 'button-press-event', self.on_button_press)
110
111 def get_length(self):
112 return(self.allocation.height)