Source code for jigsawwm.tiler.layouts

"""

The ``layout`` module operates in Relative Coordinate, to that end, it defines 2 basic types:

``FloatRect`` is a tuple with 4 elements (left/top/right/bottom) to describe a rectangle in ratio form (0.0~1.0)

``Layout`` is a generator which generates FloatRects for given total number of windows

"""

from functools import partial
from typing import Callable, Iterator, Tuple, Union

# FloatRect holds relative coordinate for rectangle (left/top/right/bottom)
FloatRect = Tuple[float, float, float, float]

# Layout accepts an integer (total number of windows) and return a FloatRect generator
Layout = Callable[[int], Iterator[FloatRect]]


[docs]def mono(n: int) -> Iterator[FloatRect]: """The mono Layout .. code-block:: text +-----------+ | | | | | | | 1 | | | | | | | +-----------+ :param n: total number of windows :rtype: Iterator[FloatRect] """ for i in range(n): yield 0.0, 0.0, 1.0, 1.0
[docs]def dwindle(n: int) -> Iterator[FloatRect]: """The dwindle Layout .. code-block:: text +-----------+-----------+ | | | | | 2 | | | | | 1 +-----+-----+ | | | 4 | | | 3 +--+--+ | | | 5|-.| +-----------+-----+-----+ :param n: total number of windows :rtype: Iterator[FloatRect] """ l, t, r, b = 0.0, 0.0, 1.0, 1.0 last_index = n - 1 for i in range(n): # last window would occupy the whole area if i == last_index: yield l, t, r, b # or it should leave out half space for the other windows elif i % 2 == 0: nl = r - (r - l) / 2 yield l, t, nl, b l = nl else: nb = b - (b - t) / 2 yield l, t, r, nb t = nb
[docs]def widescreen_dwindle(n: int, master_ratio: float = 0.4) -> Iterator[FloatRect]: """A wide-screen friendly dwindle Layout .. code-block:: text +-----------+-----------+-----------+ | | | | | | | 3 | | | | | | 1 | 2 +-----+-----+ | | | | 5 | | | | 4 +--+--+ | | | | 6|-.| +-----------+-----------+-----+-----+ :param n: total number of windows :rtype: Iterator[FloatRect] """ if n == 0: return # wide_dwindle if n == 1: yield 0.0, 0.0, 1.0, 1.0 return # master window on the left yield 0.0, 0.0, master_ratio, 1 # other windows on the right with dwindle layout, just map the coordinate and we are good yield from map( partial(plug_rect, target=(master_ratio, 0.0, 1.0, 1.0)), dwindle(n - 1) )
Number = Union[int, float] NumberRect = Tuple[Number, Number, Number, Number]
[docs]def plug_rect(source: FloatRect, target: NumberRect) -> NumberRect: """Plug the source rect into the target rect and compute the new dimensions, you may plug a Relative Rect into a Physical Rect, but not the other way around. :param source: the FloatRect to be moved :param target: the container, either a FloatRect or Rect(physical pixels) :returns: Rect or FloatRect depends on the type of the target :rtype: NumberRect """ sl, st, sr, sb = source tl, tt, tr, tb = target tw = tr - tl th = tb - tt return ( tl + sl * tw, # left = target left + scaled source left tt + st * th, # top = target top + scaled source top tl + sr * tw, # right tt + sb * th, # bottom )
if __name__ == "__main__": print("dwindle") for n in range(1, 5): print(list(dwindle(n))) print() print("widescreen_dwindle") for n in range(1, 5): print(list(widescreen_dwindle(n)))