2007-03-06 10:05:38 -05:00
|
|
|
import sets
|
2007-10-21 20:55:29 -04:00
|
|
|
import window
|
2007-03-06 10:05:38 -05:00
|
|
|
|
2008-03-14 17:17:04 -04:00
|
|
|
class Slot(object):
|
2008-04-08 09:25:56 -04:00
|
|
|
window = None
|
2008-04-06 22:31:13 -04:00
|
|
|
def __init__(self, height, width, y_offset=0, x_offset=0):
|
|
|
|
self.resize(height, width, y_offset, x_offset)
|
2007-03-06 10:05:38 -05:00
|
|
|
def is_empty(self):
|
2007-06-04 03:29:37 -04:00
|
|
|
return self.window is None
|
2008-04-06 22:31:13 -04:00
|
|
|
def resize(self, height, width, y_offset=0, x_offset=0):
|
2008-04-08 09:25:56 -04:00
|
|
|
self.height = height
|
|
|
|
self.width = width
|
|
|
|
self.y_offset = y_offset
|
|
|
|
self.x_offset = x_offset
|
2007-06-04 03:29:37 -04:00
|
|
|
if self.window is not None:
|
|
|
|
self.window.set_size(self.width, self.height)
|
|
|
|
def set(self, w):
|
2008-04-06 22:31:13 -04:00
|
|
|
self.window = w
|
|
|
|
self.resize(self.height, self.width, self.y_offset, self.x_offset)
|
2007-06-04 03:29:37 -04:00
|
|
|
w.set_size(self.width, self.height)
|
2008-04-08 09:25:56 -04:00
|
|
|
def unset(self):
|
|
|
|
if not self.is_empty():
|
|
|
|
old_w = self.window
|
|
|
|
self.window = None
|
|
|
|
return old_w
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
class Box(object):
|
|
|
|
boxtype = 'box'
|
|
|
|
def _set_hwyx(self, h, w, y, x):
|
|
|
|
self.height = h
|
|
|
|
self.width = w
|
|
|
|
self.y_offset = y
|
|
|
|
self.x_offset = x
|
|
|
|
def __init__(self, h, w, y, x):
|
|
|
|
self._set_hwyx(h, w, y, x)
|
|
|
|
def resize(self, h, w, y, x):
|
|
|
|
self._set_hwyx(h, w, y, x)
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
class VBoxes(Box):
|
|
|
|
boxtype = 'vboxes'
|
|
|
|
def __init__(self, h, w, y, x):
|
|
|
|
Box.__init__(self, h, w, y, x)
|
|
|
|
self.boxes = [Box(h, w, y, x)]
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
def rescale(self):
|
|
|
|
n = len(self.boxes)
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
# first let's divide the new space based on old proportions
|
|
|
|
oldtotal = sum([box.height for box in self.boxes])
|
|
|
|
newtotal = self.height - len(self.boxes) + 1
|
|
|
|
heights = [None] * n
|
|
|
|
for i in range(0, n):
|
|
|
|
heights[i] = int(float(newtotal * self.boxes[i]) / oldtotal)
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
# fix any rounding errors
|
|
|
|
_sum = sum([h for h in heights])
|
|
|
|
if _sum < total:
|
|
|
|
adder = 1
|
|
|
|
else:
|
|
|
|
adder = -1
|
|
|
|
for i in range(0, abs(total - _sum)):
|
|
|
|
heights[i % n] += adder
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
# now do it!
|
|
|
|
offset = self.y_offset
|
|
|
|
for i in range(0, n):
|
|
|
|
self.boxes[i].resize(heights[i], self.width, offset, self.x_offset)
|
|
|
|
offset += heights[i] + 1
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
def resize(self, height, width, y_offset, x_offset):
|
|
|
|
self.height = height
|
|
|
|
self.width = width
|
|
|
|
self.y_offset = y_offset
|
|
|
|
self.x_offset = x_offset
|
|
|
|
self.rescale()
|
2008-04-08 17:50:03 -04:00
|
|
|
|
2008-04-09 10:24:27 -04:00
|
|
|
def split_box(self, n):
|
|
|
|
for box in boxes:
|
|
|
|
b.height = 0
|
|
|
|
self.boxes.extend(boxes)
|
2007-03-06 10:05:38 -05:00
|
|
|
|
2008-03-14 17:17:04 -04:00
|
|
|
class BufferList(object):
|
2007-03-06 10:05:38 -05:00
|
|
|
def __init__(self, height, width, buffers=()):
|
2007-06-04 03:29:37 -04:00
|
|
|
self.height = height
|
|
|
|
self.width = width
|
|
|
|
self.buffers = sets.Set()
|
|
|
|
self.buffer_names = {}
|
2007-03-06 10:05:38 -05:00
|
|
|
self.hidden_buffers = []
|
2007-06-04 03:29:37 -04:00
|
|
|
self.slots = []
|
|
|
|
|
|
|
|
self.add_slot()
|
|
|
|
self.fit_slots()
|
2007-03-06 10:05:38 -05:00
|
|
|
for b in buffers:
|
|
|
|
self.add_buffer(b)
|
2007-06-04 03:29:37 -04:00
|
|
|
def fit_slots(self):
|
2007-06-04 23:05:33 -04:00
|
|
|
total = self.height - len(self.slots) + 1
|
|
|
|
heights = [total / len(self.slots)] * len(self.slots)
|
|
|
|
for i in range(0, total % len(self.slots)):
|
2007-06-04 03:29:37 -04:00
|
|
|
heights[i] += 1
|
|
|
|
offsets = [0]
|
|
|
|
for i in range(1, len(self.slots)):
|
2007-06-04 23:05:33 -04:00
|
|
|
offsets.insert(i, offsets[i - 1] + heights[i - 1] + 1)
|
2007-06-04 03:29:37 -04:00
|
|
|
for i in range(0, len(self.slots)):
|
|
|
|
self.slots[i].resize(heights[i], self.width, offsets[i])
|
|
|
|
def resize(self, height, width):
|
|
|
|
self.height = height
|
|
|
|
self.width = width
|
|
|
|
self.fit_slots()
|
|
|
|
|
|
|
|
def is_window_visible(self, w):
|
|
|
|
for slot in self.slots:
|
|
|
|
if w is slot.window:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
def is_buffer_visible(self, b):
|
|
|
|
for slot in self.slots:
|
|
|
|
if slot.window is not None and b is slot.window.buffer:
|
|
|
|
return True
|
|
|
|
return False
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
# manipulate slots
|
2007-06-04 03:29:37 -04:00
|
|
|
def add_slot(self):
|
|
|
|
self.slots.append(Slot(self.height, self.width, 0))
|
|
|
|
self.fit_slots()
|
2007-03-06 10:05:38 -05:00
|
|
|
return len(self.slots) - 1
|
|
|
|
def empty_slot(self, i):
|
|
|
|
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
|
|
|
return self.slots[i].is_empty()
|
2007-06-04 03:29:37 -04:00
|
|
|
def unset_slot(self, i):
|
|
|
|
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
|
|
|
old_w = self.slots[i].unset()
|
|
|
|
if old_w is not None:
|
|
|
|
old_b = old_w.buffer
|
|
|
|
if not self.is_buffer_visible(old_b):
|
|
|
|
self.hidden_buffers.insert(0, old_b)
|
|
|
|
if len(old_b.windows) > 1:
|
|
|
|
old_b.remove_window(old_w)
|
|
|
|
|
2007-03-06 10:05:38 -05:00
|
|
|
def set_slot(self, i, b):
|
|
|
|
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
|
|
|
assert b in self.buffers, "buffer %s does not exist" % (b.name())
|
2007-06-04 23:05:33 -04:00
|
|
|
slot = self.slots[i]
|
2007-06-04 03:29:37 -04:00
|
|
|
self.unset_slot(i)
|
|
|
|
|
2007-03-06 10:05:38 -05:00
|
|
|
if b in self.hidden_buffers:
|
|
|
|
self.hidden_buffers.remove(b)
|
2007-06-04 03:29:37 -04:00
|
|
|
if self.is_window_visible(b.windows[0]):
|
|
|
|
app = b.windows[0].application
|
2007-10-21 20:55:29 -04:00
|
|
|
w = window.Window(b, app, height=slot.height, width=slot.width)
|
2007-06-04 03:29:37 -04:00
|
|
|
else:
|
|
|
|
w = b.windows[0]
|
2007-06-04 23:05:33 -04:00
|
|
|
slot.set(w)
|
2007-06-04 03:29:37 -04:00
|
|
|
|
2007-03-06 10:05:38 -05:00
|
|
|
def remove_slot(self, i):
|
|
|
|
assert i > -1 and i < len(self.slots), "slot %d does not exist" % i
|
2007-06-04 03:29:37 -04:00
|
|
|
self.unset_slot(i)
|
2007-03-06 10:05:38 -05:00
|
|
|
del self.slots[i]
|
2007-06-04 03:29:37 -04:00
|
|
|
self.fit_slots()
|
2007-03-06 10:05:38 -05:00
|
|
|
|
|
|
|
# add/remove buffers
|
|
|
|
def add_buffer(self, b):
|
|
|
|
assert b not in self.buffers, "buffer %s already exists" % (b.name())
|
|
|
|
self.buffers.add(b)
|
|
|
|
self.buffer_names[b.name()] = b
|
|
|
|
self.hidden_buffers.append(b)
|
|
|
|
def has_buffer(self, b):
|
|
|
|
return b in self.buffers
|
|
|
|
def has_buffer_name(self, name):
|
|
|
|
return name in self.buffer_names
|
|
|
|
def get_buffer_by_name(self, name):
|
|
|
|
return self.buffer_names[name]
|
|
|
|
def get_buffer_by_path(self, path):
|
|
|
|
for b in self.buffers:
|
|
|
|
if hasattr(b, 'path') and b.path == path:
|
|
|
|
return b
|
|
|
|
return None
|
|
|
|
def remove_buffer(self, b):
|
|
|
|
assert b in self.buffers, "buffer %s does not exist" % (b.name())
|
2007-06-04 03:29:37 -04:00
|
|
|
for i in range(0, len(self.slots)):
|
|
|
|
slot = self.slots[i]
|
|
|
|
if self.slots[i].window is not None and self.slots[i].window.buffer is b:
|
|
|
|
self.unset_slot(i)
|
2007-03-06 10:05:38 -05:00
|
|
|
self.buffers.remove(b)
|
|
|
|
del self.buffer_names[b.name()]
|
|
|
|
if b in self.hidden_buffers:
|
|
|
|
self.hidden_buffers.remove(b)
|
|
|
|
|
|
|
|
# query buffers
|
|
|
|
def is_buffer_hidden(self, b):
|
|
|
|
assert b in self.buffers, "buffer %s does not exist" % (b.name())
|
|
|
|
return b in self.hidden_buffers
|