Merge lp:~andre-hilsendeger/terminator/rotate into lp:terminator/trunk

Proposed by Andre Hilsendeger
Status: Merged
Merged at revision: 1290
Proposed branch: lp:~andre-hilsendeger/terminator/rotate
Merge into: lp:terminator/trunk
Diff against target: 277 lines (+99/-19)
8 files modified
doc/terminator.1 (+6/-0)
doc/terminator_config.5 (+8/-0)
terminatorlib/config.py (+2/-0)
terminatorlib/container.py (+5/-0)
terminatorlib/paned.py (+50/-19)
terminatorlib/prefseditor.py (+2/-0)
terminatorlib/terminal.py (+8/-0)
terminatorlib/window.py (+18/-0)
To merge this branch: bzr merge lp:~andre-hilsendeger/terminator/rotate
Reviewer Review Type Date Requested Status
Chris Jones (community) Approve
Review via email: mp+100820@code.launchpad.net

Description of the change

Add functionality to rotate paned containers inside a terminator window.
VPaned becomes HPaned, and vice versa, while maintaining the split ratio.

Super+R: rotate clockwise
Super+Shift+R: rotate counter-clockwise

I've been missing this feature and maybe others too.

To post a comment you must log in.
Revision history for this message
Chris Jones (cmsj) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/terminator.1'
2--- doc/terminator.1 2010-04-09 11:31:15 +0000
3+++ doc/terminator.1 2012-04-04 16:03:19 +0000
4@@ -77,6 +77,12 @@
5 .SH "KEYBINDINGS"
6 The following keybindings can be used to control Terminator:
7 .TP
8+.B Super+R
9+\fBR\fotate terminals clockwise.
10+.TP
11+.B Super+Shift+R
12+\fBR\fotate terminals counter-clockwise.
13+.TP
14 .B Ctrl+Shift+O
15 Split terminals H\fBo\fRrizontally.
16 .TP
17
18=== modified file 'doc/terminator_config.5'
19--- doc/terminator_config.5 2012-01-14 20:39:00 +0000
20+++ doc/terminator_config.5 2012-04-04 16:03:19 +0000
21@@ -171,6 +171,14 @@
22 Move cursor focus to the terminal to the right.
23 Default value: \fB<Alt>Right\fR
24 .TP
25+.B rotate_cw
26+Rotate terminals clockwise.
27+Default value: \fB<Super>R\fR
28+.TP
29+.B rotate_ccw
30+Rotate terminals counter-clockwise.
31+Default value: \fB<Super><Shift>R\fR
32+.TP
33 .B split_horiz
34 Split the current terminal horizontally.
35 Default value: \fB<Ctrl><Shift>O\fR
36
37=== modified file 'terminatorlib/config.py'
38--- terminatorlib/config.py 2012-01-14 20:39:00 +0000
39+++ terminatorlib/config.py 2012-04-04 16:03:19 +0000
40@@ -118,6 +118,8 @@
41 'go_down' : '<Alt>Down',
42 'go_left' : '<Alt>Left',
43 'go_right' : '<Alt>Right',
44+ 'rotate_cw' : '<Super>r',
45+ 'rotate_ccw' : '<Super><Shift>r',
46 'split_horiz' : '<Shift><Control>o',
47 'split_vert' : '<Shift><Control>e',
48 'close_term' : '<Shift><Control>w',
49
50=== modified file 'terminatorlib/container.py'
51--- terminatorlib/container.py 2011-08-22 20:05:38 +0000
52+++ terminatorlib/container.py 2012-04-04 16:03:19 +0000
53@@ -80,6 +80,10 @@
54 """Default axis splitter. This should be implemented by subclasses"""
55 raise NotImplementedError('split_axis')
56
57+ def rotate(self, widget, clockwise):
58+ """Rotate children in this container"""
59+ raise NotImplementedError('rotate')
60+
61 def add(self, widget, metadata=None):
62 """Add a widget to the container"""
63 raise NotImplementedError('add')
64@@ -265,4 +269,5 @@
65 """Apply settings for our layout"""
66 raise NotImplementedError('create_layout')
67
68+
69 # vim: set expandtab ts=4 sw=4:
70
71=== modified file 'terminatorlib/paned.py'
72--- terminatorlib/paned.py 2011-08-22 20:05:38 +0000
73+++ terminatorlib/paned.py 2012-04-04 16:03:19 +0000
74@@ -19,6 +19,7 @@
75
76 position = None
77 maker = None
78+ ratio = 0.5
79
80 def __init__(self):
81 """Class initialiser"""
82@@ -32,19 +33,6 @@
83
84
85 # pylint: disable-msg=W0613
86- def set_initial_position(self, widget, event):
87- """Set the initial position of the widget"""
88- if not self.position:
89- if isinstance(self, gtk.VPaned):
90- self.position = self.allocation.height / 2
91- else:
92- self.position = self.allocation.width / 2
93-
94- dbg("Paned::set_initial_position: Setting position to: %d" % self.position)
95- self.set_position(self.position)
96- self.cnxids.remove_signal(self, 'expose-event')
97-
98- # pylint: disable-msg=W0613
99 def split_axis(self, widget, vertical=True, cwd=None, sibling=None,
100 widgetfirst=True):
101 """Default axis splitter. This should be implemented by subclasses"""
102@@ -76,13 +64,13 @@
103 def add(self, widget, metadata=None):
104 """Add a widget to the container"""
105 if len(self.children) == 0:
106- self.pack1(widget, True, True)
107+ self.pack1(widget, False, True)
108 self.children.append(widget)
109 elif len(self.children) == 1:
110 if self.get_child1():
111- self.pack2(widget, True, True)
112+ self.pack2(widget, False, True)
113 else:
114- self.pack1(widget, True, True)
115+ self.pack1(widget, False, True)
116 self.children.append(widget)
117 else:
118 raise ValueError('Paned widgets can only have two children')
119@@ -94,6 +82,7 @@
120 'split-vert': self.split_vert,
121 'title-change': self.propagate_title_change,
122 'resize-term': self.resizeterm,
123+ 'size-allocate': self.new_size,
124 'zoom': top_window.zoom,
125 'tab-change': top_window.tab_change,
126 'group-all': top_window.group_all,
127@@ -103,7 +92,9 @@
128 'move-tab': top_window.move_tab,
129 'maximise': [top_window.zoom, False],
130 'tab-new': [top_window.tab_new, widget],
131- 'navigate': top_window.navigate_terminal}
132+ 'navigate': top_window.navigate_terminal,
133+ 'rotate-cw': [top_window.rotate, True],
134+ 'rotate-ccw': [top_window.rotate, False]}
135
136 for signal in signals:
137 args = []
138@@ -118,6 +109,7 @@
139 elif isinstance(widget, gtk.Paned):
140 try:
141 self.connect_child(widget, 'resize-term', self.resizeterm)
142+ self.connect_child(widget, 'size-allocate', self.new_size)
143 except TypeError:
144 err('Paned::add: %s has no signal resize-term' % widget)
145
146@@ -260,6 +252,35 @@
147 """We don't want focus, we want a Terminal to have it"""
148 self.get_child1().grab_focus()
149
150+ def rotate(self, widget, clockwise):
151+ """Default rotation. This should be implemented by subclasses"""
152+ if isinstance(self, HPaned):
153+ container = VPaned()
154+ reverse = not clockwise
155+ else:
156+ container = HPaned()
157+ reverse = clockwise
158+
159+ container.ratio = self.ratio
160+
161+ self.get_parent().replace(self, container)
162+
163+ children = self.get_children()
164+ if reverse:
165+ container.ratio = 1 - container.ratio
166+ children.reverse()
167+
168+ for child in children:
169+ self.remove(child)
170+ container.add(child)
171+
172+ def new_size(self, widget, allocation):
173+ self.set_pos(int(self.ratio*self.get_length()))
174+
175+ def set_position(self, pos):
176+ self.ratio = float(pos) / self.get_length()
177+ self.set_pos(pos)
178+
179 class HPaned(Paned, gtk.HPaned):
180 """Merge gtk.HPaned into our base Paned Container"""
181 def __init__(self):
182@@ -267,7 +288,12 @@
183 Paned.__init__(self)
184 gtk.HPaned.__init__(self)
185 self.register_signals(HPaned)
186- self.cnxids.new(self, 'expose-event', self.set_initial_position)
187+
188+ def get_length(self):
189+ return(self.allocation.width)
190+
191+ def set_pos(self, pos):
192+ gtk.HPaned.set_position(self, pos)
193
194 class VPaned(Paned, gtk.VPaned):
195 """Merge gtk.VPaned into our base Paned Container"""
196@@ -276,7 +302,12 @@
197 Paned.__init__(self)
198 gtk.VPaned.__init__(self)
199 self.register_signals(VPaned)
200- self.cnxids.new(self, 'expose-event', self.set_initial_position)
201+
202+ def get_length(self):
203+ return(self.allocation.height)
204+
205+ def set_pos(self, pos):
206+ gtk.VPaned.set_position(self, pos)
207
208 gobject.type_register(HPaned)
209 gobject.type_register(VPaned)
210
211=== modified file 'terminatorlib/prefseditor.py'
212--- terminatorlib/prefseditor.py 2012-01-14 20:39:00 +0000
213+++ terminatorlib/prefseditor.py 2012-04-04 16:03:19 +0000
214@@ -84,6 +84,8 @@
215 'go_down' : 'Focus the terminal below',
216 'go_left' : 'Focus the terminal left',
217 'go_right' : 'Focus the terminal right',
218+ 'rotate_cw' : 'Rotate terminals clockwise',
219+ 'rotate_ccw' : 'Rotate terminals counter-clockwise',
220 'split_horiz' : 'Split horizontally',
221 'split_vert' : 'Split vertically',
222 'close_term' : 'Close terminal',
223
224=== modified file 'terminatorlib/terminal.py'
225--- terminatorlib/terminal.py 2012-01-14 20:39:00 +0000
226+++ terminatorlib/terminal.py 2012-04-04 16:03:19 +0000
227@@ -52,6 +52,8 @@
228 (gobject.TYPE_STRING,)),
229 'split-vert': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
230 (gobject.TYPE_STRING,)),
231+ 'rotate-cw': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
232+ 'rotate-ccw': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
233 'tab-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
234 (gobject.TYPE_BOOLEAN, gobject.TYPE_OBJECT)),
235 'tab-top-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
236@@ -1509,6 +1511,12 @@
237 def key_split_vert(self):
238 self.emit('split-vert', self.terminator.pid_cwd(self.pid))
239
240+ def key_rotate_cw(self):
241+ self.emit('rotate-cw')
242+
243+ def key_rotate_ccw(self):
244+ self.emit('rotate-ccw')
245+
246 def key_close_term(self):
247 self.close()
248
249
250=== modified file 'terminatorlib/window.py'
251--- terminatorlib/window.py 2011-08-22 20:05:38 +0000
252+++ terminatorlib/window.py 2012-04-04 16:03:19 +0000
253@@ -479,6 +479,24 @@
254 self.zoom_data = None
255 self.set_property('term_zoomed', False)
256
257+ def rotate(self, widget, clockwise):
258+ """Rotate children in this window"""
259+ maker = Factory()
260+ # collect all paned children in breadth-first order
261+ paned = []
262+ for child in self.get_children():
263+ if maker.isinstance(child, 'Paned'):
264+ paned.append(child)
265+ for p in paned:
266+ for child in p.get_children():
267+ if child not in paned and maker.isinstance(child, 'Paned'):
268+ paned.append(child)
269+ # then propagate the rotation
270+ for p in paned:
271+ p.rotate(widget, clockwise)
272+ self.show_all()
273+ widget.grab_focus()
274+
275 def get_visible_terminals(self):
276 """Walk down the widget tree to find all of the visible terminals.
277 Mostly using Container::get_visible_terminals()"""