Add possibility to rotate the paned containers.
This commit is contained in:
parent
f8b59348c6
commit
e95bdcf964
|
@ -77,6 +77,12 @@ will be displayed
|
|||
.SH "KEYBINDINGS"
|
||||
The following keybindings can be used to control Terminator:
|
||||
.TP
|
||||
.B Super+R
|
||||
\fBR\fotate terminals clockwise.
|
||||
.TP
|
||||
.B Super+Shift+R
|
||||
\fBR\fotate terminals counter-clockwise.
|
||||
.TP
|
||||
.B Ctrl+Shift+O
|
||||
Split terminals H\fBo\fRrizontally.
|
||||
.TP
|
||||
|
|
|
@ -171,6 +171,14 @@ Default value: \fB<Alt>Left\fR
|
|||
Move cursor focus to the terminal to the right.
|
||||
Default value: \fB<Alt>Right\fR
|
||||
.TP
|
||||
.B rotate_cw
|
||||
Rotate terminals clockwise.
|
||||
Default value: \fB<Super>R\fR
|
||||
.TP
|
||||
.B rotate_ccw
|
||||
Rotate terminals counter-clockwise.
|
||||
Default value: \fB<Super><Shift>R\fR
|
||||
.TP
|
||||
.B split_horiz
|
||||
Split the current terminal horizontally.
|
||||
Default value: \fB<Ctrl><Shift>O\fR
|
||||
|
|
|
@ -118,6 +118,8 @@ DEFAULTS = {
|
|||
'go_down' : '<Alt>Down',
|
||||
'go_left' : '<Alt>Left',
|
||||
'go_right' : '<Alt>Right',
|
||||
'rotate_cw' : '<Super>r',
|
||||
'rotate_ccw' : '<Super><Shift>r',
|
||||
'split_horiz' : '<Shift><Control>o',
|
||||
'split_vert' : '<Shift><Control>e',
|
||||
'close_term' : '<Shift><Control>w',
|
||||
|
|
|
@ -80,6 +80,10 @@ class Container(object):
|
|||
"""Default axis splitter. This should be implemented by subclasses"""
|
||||
raise NotImplementedError('split_axis')
|
||||
|
||||
def rotate(self, widget, clockwise):
|
||||
"""Rotate children in this container"""
|
||||
raise NotImplementedError('rotate')
|
||||
|
||||
def add(self, widget, metadata=None):
|
||||
"""Add a widget to the container"""
|
||||
raise NotImplementedError('add')
|
||||
|
@ -265,4 +269,5 @@ the %s will also close all terminals within it.') % (reqtype, reqtype))
|
|||
"""Apply settings for our layout"""
|
||||
raise NotImplementedError('create_layout')
|
||||
|
||||
|
||||
# vim: set expandtab ts=4 sw=4:
|
||||
|
|
|
@ -19,6 +19,7 @@ class Paned(Container):
|
|||
|
||||
position = None
|
||||
maker = None
|
||||
ratio = 0.5
|
||||
|
||||
def __init__(self):
|
||||
"""Class initialiser"""
|
||||
|
@ -31,19 +32,6 @@ class Paned(Container):
|
|||
'param_types': (gobject.TYPE_STRING,)})
|
||||
|
||||
|
||||
# pylint: disable-msg=W0613
|
||||
def set_initial_position(self, widget, event):
|
||||
"""Set the initial position of the widget"""
|
||||
if not self.position:
|
||||
if isinstance(self, gtk.VPaned):
|
||||
self.position = self.allocation.height / 2
|
||||
else:
|
||||
self.position = self.allocation.width / 2
|
||||
|
||||
dbg("Paned::set_initial_position: Setting position to: %d" % self.position)
|
||||
self.set_position(self.position)
|
||||
self.cnxids.remove_signal(self, 'expose-event')
|
||||
|
||||
# pylint: disable-msg=W0613
|
||||
def split_axis(self, widget, vertical=True, cwd=None, sibling=None,
|
||||
widgetfirst=True):
|
||||
|
@ -76,13 +64,13 @@ class Paned(Container):
|
|||
def add(self, widget, metadata=None):
|
||||
"""Add a widget to the container"""
|
||||
if len(self.children) == 0:
|
||||
self.pack1(widget, True, True)
|
||||
self.pack1(widget, False, True)
|
||||
self.children.append(widget)
|
||||
elif len(self.children) == 1:
|
||||
if self.get_child1():
|
||||
self.pack2(widget, True, True)
|
||||
self.pack2(widget, False, True)
|
||||
else:
|
||||
self.pack1(widget, True, True)
|
||||
self.pack1(widget, False, True)
|
||||
self.children.append(widget)
|
||||
else:
|
||||
raise ValueError('Paned widgets can only have two children')
|
||||
|
@ -94,6 +82,7 @@ class Paned(Container):
|
|||
'split-vert': self.split_vert,
|
||||
'title-change': self.propagate_title_change,
|
||||
'resize-term': self.resizeterm,
|
||||
'size-allocate': self.new_size,
|
||||
'zoom': top_window.zoom,
|
||||
'tab-change': top_window.tab_change,
|
||||
'group-all': top_window.group_all,
|
||||
|
@ -103,7 +92,9 @@ class Paned(Container):
|
|||
'move-tab': top_window.move_tab,
|
||||
'maximise': [top_window.zoom, False],
|
||||
'tab-new': [top_window.tab_new, widget],
|
||||
'navigate': top_window.navigate_terminal}
|
||||
'navigate': top_window.navigate_terminal,
|
||||
'rotate-cw': [top_window.rotate, True],
|
||||
'rotate-ccw': [top_window.rotate, False]}
|
||||
|
||||
for signal in signals:
|
||||
args = []
|
||||
|
@ -118,6 +109,7 @@ class Paned(Container):
|
|||
elif isinstance(widget, gtk.Paned):
|
||||
try:
|
||||
self.connect_child(widget, 'resize-term', self.resizeterm)
|
||||
self.connect_child(widget, 'size-allocate', self.new_size)
|
||||
except TypeError:
|
||||
err('Paned::add: %s has no signal resize-term' % widget)
|
||||
|
||||
|
@ -260,6 +252,35 @@ class Paned(Container):
|
|||
"""We don't want focus, we want a Terminal to have it"""
|
||||
self.get_child1().grab_focus()
|
||||
|
||||
def rotate(self, widget, clockwise):
|
||||
"""Default rotation. This should be implemented by subclasses"""
|
||||
if isinstance(self, HPaned):
|
||||
container = VPaned()
|
||||
reverse = not clockwise
|
||||
else:
|
||||
container = HPaned()
|
||||
reverse = clockwise
|
||||
|
||||
container.ratio = self.ratio
|
||||
|
||||
self.get_parent().replace(self, container)
|
||||
|
||||
children = self.get_children()
|
||||
if reverse:
|
||||
container.ratio = 1 - container.ratio
|
||||
children.reverse()
|
||||
|
||||
for child in children:
|
||||
self.remove(child)
|
||||
container.add(child)
|
||||
|
||||
def new_size(self, widget, allocation):
|
||||
self.set_pos(int(self.ratio*self.get_length()))
|
||||
|
||||
def set_position(self, pos):
|
||||
self.ratio = float(pos) / self.get_length()
|
||||
self.set_pos(pos)
|
||||
|
||||
class HPaned(Paned, gtk.HPaned):
|
||||
"""Merge gtk.HPaned into our base Paned Container"""
|
||||
def __init__(self):
|
||||
|
@ -267,7 +288,12 @@ class HPaned(Paned, gtk.HPaned):
|
|||
Paned.__init__(self)
|
||||
gtk.HPaned.__init__(self)
|
||||
self.register_signals(HPaned)
|
||||
self.cnxids.new(self, 'expose-event', self.set_initial_position)
|
||||
|
||||
def get_length(self):
|
||||
return(self.allocation.width)
|
||||
|
||||
def set_pos(self, pos):
|
||||
gtk.HPaned.set_position(self, pos)
|
||||
|
||||
class VPaned(Paned, gtk.VPaned):
|
||||
"""Merge gtk.VPaned into our base Paned Container"""
|
||||
|
@ -276,7 +302,12 @@ class VPaned(Paned, gtk.VPaned):
|
|||
Paned.__init__(self)
|
||||
gtk.VPaned.__init__(self)
|
||||
self.register_signals(VPaned)
|
||||
self.cnxids.new(self, 'expose-event', self.set_initial_position)
|
||||
|
||||
def get_length(self):
|
||||
return(self.allocation.height)
|
||||
|
||||
def set_pos(self, pos):
|
||||
gtk.VPaned.set_position(self, pos)
|
||||
|
||||
gobject.type_register(HPaned)
|
||||
gobject.type_register(VPaned)
|
||||
|
|
|
@ -84,6 +84,8 @@ class PrefsEditor:
|
|||
'go_down' : 'Focus the terminal below',
|
||||
'go_left' : 'Focus the terminal left',
|
||||
'go_right' : 'Focus the terminal right',
|
||||
'rotate_cw' : 'Rotate terminals clockwise',
|
||||
'rotate_ccw' : 'Rotate terminals counter-clockwise',
|
||||
'split_horiz' : 'Split horizontally',
|
||||
'split_vert' : 'Split vertically',
|
||||
'close_term' : 'Close terminal',
|
||||
|
|
|
@ -52,6 +52,8 @@ class Terminal(gtk.VBox):
|
|||
(gobject.TYPE_STRING,)),
|
||||
'split-vert': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
|
||||
(gobject.TYPE_STRING,)),
|
||||
'rotate-cw': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
|
||||
'rotate-ccw': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
|
||||
'tab-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
|
||||
(gobject.TYPE_BOOLEAN, gobject.TYPE_OBJECT)),
|
||||
'tab-top-new': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
|
||||
|
@ -1509,6 +1511,12 @@ class Terminal(gtk.VBox):
|
|||
def key_split_vert(self):
|
||||
self.emit('split-vert', self.terminator.pid_cwd(self.pid))
|
||||
|
||||
def key_rotate_cw(self):
|
||||
self.emit('rotate-cw')
|
||||
|
||||
def key_rotate_ccw(self):
|
||||
self.emit('rotate-ccw')
|
||||
|
||||
def key_close_term(self):
|
||||
self.close()
|
||||
|
||||
|
|
|
@ -479,6 +479,24 @@ class Window(Container, gtk.Window):
|
|||
self.zoom_data = None
|
||||
self.set_property('term_zoomed', False)
|
||||
|
||||
def rotate(self, widget, clockwise):
|
||||
"""Rotate children in this window"""
|
||||
maker = Factory()
|
||||
# collect all paned children in breadth-first order
|
||||
paned = []
|
||||
for child in self.get_children():
|
||||
if maker.isinstance(child, 'Paned'):
|
||||
paned.append(child)
|
||||
for p in paned:
|
||||
for child in p.get_children():
|
||||
if child not in paned and maker.isinstance(child, 'Paned'):
|
||||
paned.append(child)
|
||||
# then propagate the rotation
|
||||
for p in paned:
|
||||
p.rotate(widget, clockwise)
|
||||
self.show_all()
|
||||
widget.grab_focus()
|
||||
|
||||
def get_visible_terminals(self):
|
||||
"""Walk down the widget tree to find all of the visible terminals.
|
||||
Mostly using Container::get_visible_terminals()"""
|
||||
|
|
Loading…
Reference in New Issue