import sets import window class Slot(object): window = None def __init__(self, height, width, y_offset=0, x_offset=0): self.resize(height, width, y_offset, x_offset) def is_empty(self): return self.window is None def resize(self, height, width, y_offset=0, x_offset=0): self.height = height self.width = width self.y_offset = y_offset self.x_offset = x_offset if self.window is not None: self.window.set_size(self.width, self.height) def set(self, w): self.window = w self.resize(self.height, self.width, self.y_offset, self.x_offset) w.set_size(self.width, self.height) def unset(self): if not self.is_empty(): old_w = self.window self.window = None return old_w else: return None 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) 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)] def rescale(self): n = len(self.boxes) # 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) # 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 # 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 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() def split_box(self, n): for box in boxes: b.height = 0 self.boxes.extend(boxes) class BufferList(object): def __init__(self, height, width, buffers=()): self.height = height self.width = width self.buffers = sets.Set() self.buffer_names = {} self.hidden_buffers = [] self.slots = [] self.add_slot() self.fit_slots() for b in buffers: self.add_buffer(b) def fit_slots(self): total = self.height - len(self.slots) + 1 heights = [total / len(self.slots)] * len(self.slots) for i in range(0, total % len(self.slots)): heights[i] += 1 offsets = [0] for i in range(1, len(self.slots)): offsets.insert(i, offsets[i - 1] + heights[i - 1] + 1) 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 # manipulate slots def add_slot(self): self.slots.append(Slot(self.height, self.width, 0)) self.fit_slots() 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() 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) 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()) slot = self.slots[i] self.unset_slot(i) if b in self.hidden_buffers: self.hidden_buffers.remove(b) if self.is_window_visible(b.windows[0]): app = b.windows[0].application w = window.Window(b, app, height=slot.height, width=slot.width) else: w = b.windows[0] slot.set(w) def remove_slot(self, i): assert i > -1 and i < len(self.slots), "slot %d does not exist" % i self.unset_slot(i) del self.slots[i] self.fit_slots() # 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()) 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) 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