def __init__(self, win, position, gravity, size, width, height, cycle): self.win_id = win.id self.args = (position, gravity, size, width, height ) # TODO: remove me!? self.gravity = gravity workarea = WM.workarea_geometry self.position = absolute_position(workarea, position) self.sizes = absolute_size(win, workarea, size, width, height) dummy = DummyWindow(win, self.position, self.sizes, self.gravity) max_geo = expand_window(dummy, dummy.gravity, sticky=False, vertical_first=cycle) widths = [] for width in self.sizes.width: if max_geo.width - width >= 0 and \ self.position.x - width * position.x >= max_geo.x and \ self.position.x + width * (1 - position.x) <= max_geo.x2: widths.append(width) heights = [] for height in self.sizes.height: if max_geo.height - height >= 0 and \ self.position.y - height * position.y >= max_geo.y and \ self.position.y + height * (1 - position.y) <= max_geo.y2: heights.append(height) width = max(widths) height = max(heights) self.sizes_iterator = Size(get_iterator(self.sizes.width, width), get_iterator(self.sizes.height, height)) [self.sizes_iterator.height, self.sizes_iterator.width][cycle].next() self.previous = Geometry(self.position.x, self.position.y, width, height, self.gravity)
def size_callback(option, opt_str, value, parser): """Parse width, height, size options to Size.""" largs_callback(option, opt_str, value, parser) # TODO: allow relative size, and absolute size try: if option.dest == 'width': width = Size.parse_value(value) size = Size(width, 0) elif option.dest == 'height': height = Size.parse_value(value) size = Size(0, height) elif option.dest == 'size': size = Size.parse(*value) except (ValueError, TypeError): msg = 'option %s: error parsing Size value: %s' % (opt_str, value) raise optparse.OptionValueError(msg) setattr(parser.values, option.dest, size)
def next(self, cycle): """Return new window geometry.""" if cycle == CYCLE_WIDTH: width = self.sizes_iterator.width.next() height = self.previous.height if cycle == CYCLE_HEIGHT: width = self.previous.width height = self.sizes_iterator.height.next() self.previous = Size(width, height) return Geometry(self.position.x, self.position.y, width, height, self.gravity)
def test_parse(self): self.assertEqual(Size.parse('', ''), None) self.assertEqual(Size.parse('', 'FULL'), None) self.assertEqual(Size.parse('HALF', ''), None) self.assertEqual(Size.parse('HALF', 'FULL'), self.HALF_FULL) self.assertEqual(Size.parse('HALF', '1'), self.HALF_FULL) self.assertEqual(Size.parse('HALF', '1.0'), self.HALF_FULL) self.assertEqual(Size.parse('HALF', 'HALF*2'), self.HALF_FULL) self.assertEqual(Size.parse('HALF', 'QUARTER*2+HALF'), self.HALF_FULL) self.assertEqual(Size.parse('1.0/2', '0.1*6-0.1+HALF'), self.HALF_FULL) self.assertEqual(Size.parse('HALF, FULL', '1'), Size([0.5, 1], 1)) self.assertRaises(ValueError, Size.parse, 'tttgf', '0')
def test_area(self): self.assertEqual(Size.parse('HALF', 'FULL').area, 0.5) self.assertEqual(Size.parse('HALF', '1').area, 0.5) self.assertEqual(Size.parse('HALF', '1.0').area, 0.5) self.assertEqual(Size.parse('HALF', 'HALF*2').area, 0.5) self.assertEqual(Size.parse('HALF', 'QUARTER*2+HALF').area, 0.5) self.assertEqual(Size.parse('1.0/2', '0.1*6-0.1+HALF').area, 0.5) self.assertEqual(Size(10, 10).area, 100) try: # assertRaises doesn't work with properties Size.parse('HALF, FULL', '1').area except ValueError: # "Size.area doesn't support multiple dimensions" pass else: raise AssertionError
def absolute_size(win, workarea, size, width, height): """Return Size containing sorted lists of absolute sizes.""" widths = width.width or size.width or \ float(win.width) / workarea.width heights = height.height or size.height or \ float(win.height) / workarea.height try: widths = set([min([width * workarea.width, workarea.width]) for width in widths]) except TypeError: widths = [min([widths * workarea.width, workarea.width])] try: heights = set([min([height * workarea.height, workarea.height]) for height in heights]) except TypeError: heights = [min([heights * workarea.height, workarea.height])] return Size(sorted(widths), sorted(heights))
"""grid_actions.py - PyWO actions - placing windows on grid.""" import itertools import logging from pywo.core import Gravity, Geometry, Size, Position, WindowManager from pywo.actions import Action, TYPE_FILTER from pywo.actions.resizer import expand_window __author__ = "Wojciech 'KosciaK' Pietrzok" log = logging.getLogger(__name__) WM = WindowManager() NO_SIZE = Size(0, 0) CYCLE_WIDTH = 0 CYCLE_HEIGHT = 1 class DummyWindow(object): """Dummy Window object, only geometry information is needed.""" gravity = Gravity(0.5, 0.5) def __init__(self, window, position, size, gravity): self.extents = window.extents self.desktop = window.desktop self.id = window.id self.geometry = Geometry(position.x, position.y, min(size.width),
def setUp(self): self.HALF_FULL = Size(0.5, 1.0)