Implement adding of windows to splits layout
This commit is contained in:
parent
a99caed693
commit
c788e30b66
@ -73,12 +73,15 @@ newly launched child process.
|
|||||||
--location
|
--location
|
||||||
type=choices
|
type=choices
|
||||||
default=last
|
default=last
|
||||||
choices=first,after,before,neighbor,last
|
choices=first,after,before,neighbor,last,vsplit,hsplit
|
||||||
Where to place the newly created window when it is added to a tab which
|
Where to place the newly created window when it is added to a tab which
|
||||||
already has existing windows in it. :code:`after` and :code:`before` place the new
|
already has existing windows in it. :code:`after` and :code:`before` place the new
|
||||||
window before or after the active window. :code:`neighbor` is a synonym for :code:`after`.
|
window before or after the active window. :code:`neighbor` is a synonym for :code:`after`.
|
||||||
Also applies to creating a new tab, where the value of :code:`after`
|
Also applies to creating a new tab, where the value of :code:`after`
|
||||||
will cause the new tab to be placed next to the current tab instead of at the end.
|
will cause the new tab to be placed next to the current tab instead of at the end.
|
||||||
|
The values of :code:`vsplit` and :code:`hsplit` are only used by the :code:`splits`
|
||||||
|
layout and control if the new window is placed in a vertical or horizontal split
|
||||||
|
with the currently active window.
|
||||||
|
|
||||||
|
|
||||||
--allow-remote-control
|
--allow-remote-control
|
||||||
|
|||||||
@ -279,10 +279,19 @@ class Layout: # {{{
|
|||||||
all_windows.append(all_windows[i])
|
all_windows.append(all_windows[i])
|
||||||
all_windows[i] = window
|
all_windows[i] = window
|
||||||
active_window_idx = i
|
active_window_idx = i
|
||||||
elif location is not None:
|
if active_window_idx is None:
|
||||||
if location == 'neighbor':
|
if location == 'neighbor':
|
||||||
location = 'after'
|
location = 'after'
|
||||||
if location == 'after' and current_active_window_idx is not None and len(all_windows) > 1:
|
active_window_idx = self.do_add_window(all_windows, window, current_active_window_idx, location)
|
||||||
|
|
||||||
|
self(all_windows, active_window_idx)
|
||||||
|
self.set_active_window_in_os_window(active_window_idx)
|
||||||
|
return active_window_idx
|
||||||
|
|
||||||
|
def do_add_window(self, all_windows, window, current_active_window_idx, location):
|
||||||
|
active_window_idx = None
|
||||||
|
if location is not None:
|
||||||
|
if location in ('after', 'vsplit', 'hsplit') and current_active_window_idx is not None and len(all_windows) > 1:
|
||||||
active_window_idx = min(current_active_window_idx + 1, len(all_windows))
|
active_window_idx = min(current_active_window_idx + 1, len(all_windows))
|
||||||
elif location == 'before' and current_active_window_idx is not None and len(all_windows) > 1:
|
elif location == 'before' and current_active_window_idx is not None and len(all_windows) > 1:
|
||||||
active_window_idx = current_active_window_idx
|
active_window_idx = current_active_window_idx
|
||||||
@ -296,8 +305,6 @@ class Layout: # {{{
|
|||||||
if active_window_idx is None:
|
if active_window_idx is None:
|
||||||
active_window_idx = len(all_windows)
|
active_window_idx = len(all_windows)
|
||||||
all_windows.append(window)
|
all_windows.append(window)
|
||||||
self(all_windows, active_window_idx)
|
|
||||||
self.set_active_window_in_os_window(active_window_idx)
|
|
||||||
return active_window_idx
|
return active_window_idx
|
||||||
|
|
||||||
def remove_window(self, all_windows, window, current_active_window_idx, swapped=False):
|
def remove_window(self, all_windows, window, current_active_window_idx, swapped=False):
|
||||||
@ -973,6 +980,16 @@ class Pair:
|
|||||||
if isinstance(self.two, Pair):
|
if isinstance(self.two, Pair):
|
||||||
yield from self.two.self_and_descendants()
|
yield from self.two.self_and_descendants()
|
||||||
|
|
||||||
|
def pair_for_window(self, window_id):
|
||||||
|
if self.one == window_id or self.two == window_id:
|
||||||
|
return self
|
||||||
|
ans = None
|
||||||
|
if isinstance(self.one, Pair):
|
||||||
|
ans = self.one.pair_for_window(window_id)
|
||||||
|
if ans is None and isinstance(self.two, Pair):
|
||||||
|
ans = self.two.pair_for_window(window_id)
|
||||||
|
return ans
|
||||||
|
|
||||||
def remove_windows(self, window_ids):
|
def remove_windows(self, window_ids):
|
||||||
if isinstance(self.one, int) and self.one in window_ids:
|
if isinstance(self.one, int) and self.one in window_ids:
|
||||||
self.one = None
|
self.one = None
|
||||||
@ -1025,6 +1042,21 @@ class Pair:
|
|||||||
pair.balanced_add(window_id)
|
pair.balanced_add(window_id)
|
||||||
return pair
|
return pair
|
||||||
|
|
||||||
|
def split_and_add(self, existing_window_id, new_window_id, horizontal, after):
|
||||||
|
q = (existing_window_id, new_window_id) if after else (new_window_id, existing_window_id)
|
||||||
|
if self.is_redundant:
|
||||||
|
pair = self
|
||||||
|
pair.horizontal = horizontal
|
||||||
|
self.one, self.two = q
|
||||||
|
else:
|
||||||
|
pair = Pair(horizontal=horizontal)
|
||||||
|
if self.one == existing_window_id:
|
||||||
|
self.one = pair
|
||||||
|
else:
|
||||||
|
self.two = pair
|
||||||
|
tuple(map(pair.balanced_add, q))
|
||||||
|
return pair
|
||||||
|
|
||||||
def apply_window_geometry(self, window_id, window_geometry, id_window_map, id_idx_map):
|
def apply_window_geometry(self, window_id, window_geometry, id_window_map, id_idx_map):
|
||||||
w = id_window_map[window_id]
|
w = id_window_map[window_id]
|
||||||
w.set_geometry(id_idx_map[window_id], window_geometry)
|
w.set_geometry(id_idx_map[window_id], window_geometry)
|
||||||
@ -1083,6 +1115,17 @@ class Splits(Layout):
|
|||||||
def default_axis_is_horizontal(self):
|
def default_axis_is_horizontal(self):
|
||||||
return self.layout_opts['default_axis_is_horizontal']
|
return self.layout_opts['default_axis_is_horizontal']
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pairs_root(self):
|
||||||
|
root = getattr(self, '_pairs_root', None)
|
||||||
|
if root is None:
|
||||||
|
self._pairs_root = root = Pair(horizontal=self.default_axis_is_horizontal)
|
||||||
|
return root
|
||||||
|
|
||||||
|
@pairs_root.setter
|
||||||
|
def pairs_root(self, root):
|
||||||
|
self._pairs_root = root
|
||||||
|
|
||||||
def parse_layout_opts(self, layout_opts):
|
def parse_layout_opts(self, layout_opts):
|
||||||
ans = Layout.parse_layout_opts(self, layout_opts)
|
ans = Layout.parse_layout_opts(self, layout_opts)
|
||||||
ans['default_axis_is_horizontal'] = ans.get('split_axis', 'horizontal') == 'horizontal'
|
ans['default_axis_is_horizontal'] = ans.get('split_axis', 'horizontal') == 'horizontal'
|
||||||
@ -1090,9 +1133,7 @@ class Splits(Layout):
|
|||||||
|
|
||||||
def do_layout(self, windows, active_window_idx, all_windows):
|
def do_layout(self, windows, active_window_idx, all_windows):
|
||||||
window_count = len(windows)
|
window_count = len(windows)
|
||||||
root = getattr(self, 'pairs_root', None)
|
root = self.pairs_root
|
||||||
if root is None:
|
|
||||||
self.pairs_root = root = Pair(horizontal=self.default_axis_is_horizontal)
|
|
||||||
all_present_window_ids = frozenset(w.overlay_for or w.id for w in windows)
|
all_present_window_ids = frozenset(w.overlay_for or w.id for w in windows)
|
||||||
already_placed_window_ids = frozenset(root.all_window_ids())
|
already_placed_window_ids = frozenset(root.all_window_ids())
|
||||||
windows_to_remove = already_placed_window_ids - all_present_window_ids
|
windows_to_remove = already_placed_window_ids - all_present_window_ids
|
||||||
@ -1117,6 +1158,34 @@ class Splits(Layout):
|
|||||||
else:
|
else:
|
||||||
root.layout_pair(central.left, central.top, central.width, central.height, id_window_map, id_idx_map, self)
|
root.layout_pair(central.left, central.top, central.width, central.height, id_window_map, id_idx_map, self)
|
||||||
|
|
||||||
|
def do_add_window(self, all_windows, window, current_active_window_idx, location):
|
||||||
|
horizontal = self.default_axis_is_horizontal
|
||||||
|
after = True
|
||||||
|
if location is not None:
|
||||||
|
if location == 'vsplit':
|
||||||
|
horizontal = True
|
||||||
|
elif location == 'hsplit':
|
||||||
|
horizontal = False
|
||||||
|
if location in ('before', 'first'):
|
||||||
|
after = False
|
||||||
|
active_window_idx = None
|
||||||
|
if 0 <= current_active_window_idx < len(all_windows):
|
||||||
|
cw = all_windows[current_active_window_idx]
|
||||||
|
window_id = cw.overlay_for or cw.id
|
||||||
|
pair = self.pairs_root.pair_for_window(window_id)
|
||||||
|
if pair is not None:
|
||||||
|
pair.split_and_add(window_id, window.id, horizontal, after)
|
||||||
|
active_window_idx = current_active_window_idx
|
||||||
|
if after:
|
||||||
|
active_window_idx += 1
|
||||||
|
for i in range(len(all_windows), active_window_idx, -1):
|
||||||
|
self.swap_windows_in_os_window(i, i - 1)
|
||||||
|
all_windows.insert(active_window_idx, window)
|
||||||
|
if active_window_idx is None:
|
||||||
|
active_window_idx = len(all_windows)
|
||||||
|
all_windows.append(window)
|
||||||
|
return active_window_idx
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user