multistream/frontend/layouts.py
File Type: text/x-script.python
#layouts module
import copy
MAX_STREAMS = 8
STREAM = 'stream'
CHAT = 'chat'
class Rect(object):
def __init__(self, dim, pos):
self.dim = {'x': dim[0], 'y': dim[1]}
self.pos = {'x': pos[0], 'y': pos[1]}
def scale(self, factor):
obj = self.__class__([self.dim['x'], self.dim['y']], [self.pos['x'], self.pos['y']])
obj.dim = dict([(k, int(v / factor)) for k,v in obj.dim.items()])
obj.pos = dict([(k, int(v / factor)) for k,v in obj.pos.items()])
return obj
def overlapping(self,other_chat):
return self.pos == other_chat.pos
def __repr__(self):
return '<%s %s %s>' % (self.__class__.__name__, (self.dim['x'], self.dim['y']), (self.pos['x'], self.pos['y']))
class Stream(Rect):
def __init__(self, dim, pos):
Rect.__init__(self, dim, pos)
self.objtype = STREAM
class Chat(Rect):
def __init__(self, dim, pos):
Rect.__init__(self, dim, pos)
self.objtype = CHAT
class Layout(object):
def __init__(self, objs):
self.streams = [x for x in objs if x.objtype == STREAM]
self.chats = [x for x in objs if x.objtype == CHAT]
if len(self.chats) < len(self.streams) and len(self.chats) > 0:
self.chats = [copy.deepcopy(self.chats[((c+1) % len(self.chats))-1]) for c in range(len(self.streams))]
for chat in self.chats:
chat.overlapped_chats = [c for c in self.chats if c.overlapping(chat)]
def objects(self):
return self.streams + self.chats
def scale(self, factor):
return Layout([obj.scale(factor) for obj in self.objects()])
def scale_x(self, width):
factor = self.max_x() * 1.0 / width
return self.scale(factor)
def assign_tags(self, stream_tags):
if len(stream_tags) > len(self.streams):
stream_tags = stream_tags[:len(self.streams)]
else:
stream_tags = stream_tags + [None]*(len(self.streams)-len(stream_tags))
if len(self.chats) > 0:
for stream, chat, stream_tag in zip(self.streams, self.chats, stream_tags):
stream.tag = stream_tag
chat.tag = stream_tag
else:
for stream, stream_tag in zip(self.streams, stream_tags):
stream.tag = stream_tag
def assign_indexes(self):
if len(self.chats) > 0:
self.has_chat = True
for i, stream, chat in zip(range(len(self.streams)), self.streams, self.chats):
stream.index = i
chat.index = i
else:
self.has_chat = False
for i, stream in zip(range(len(self.streams)), self.streams):
stream.index = i
def max_x(self):
return max([obj.dim['x'] + obj.pos['x'] for obj in self.objects()])
def max_y(self):
return max([obj.dim['y'] + obj.pos['y'] for obj in self.objects()])
def _initialize_layouts(layouts):
for i,layout in enumerate(layouts):
layout.scaled_thumb = layout.scale_x(140)
layout.scaled_tiny = layout.scale_x(50)
layout.index = i
layout.assign_indexes()
d_layout_groups = {}
for layout in layouts:
num_streams = len(layout.streams)
if num_streams not in d_layout_groups:
d_layout_groups[num_streams] = []
d_layout_groups[num_streams].append(layout)
groups = []
for num_streams in range(min(d_layout_groups.keys()), max(d_layout_groups.keys()) + 1):
groups.append(d_layout_groups[num_streams])
return groups
STREAM_LAYOUTS = [
# Object((Position%),(Size%))
# 1 stream
Layout([
Stream((75,100),(0,0)),
Chat((25,100),(75,0)),
]),
Layout([
Stream((100,60),(0,0)),
Chat((100,40),(0,60)),
]),
Layout([
Stream((100,100),(0,0)),
]),
# 2 streams
Layout([
Stream((75,50),(0,0)), Chat((25,100),(75,0)),
Stream((75,50),(0,50)),
]),
Layout([
Stream((50,58),(0,0)), Stream((50,58),(50,0)),
Chat((50,42),(0,58)), Chat((50,42),(50,58)),
]),
Layout([
Stream((100,50),(0,0)),
Stream((100,50),(0,50)),
]),
# 3 streams
Layout([
Stream((75,65),(0,0)), Chat((25,100),(75,0)),
Stream((37,35),(0,65)), Stream((38, 35),(37,65)),
]),
Layout([
Stream((50, 50),(0,0)), Stream((50,50),(50,0)),
Stream((50, 50),(0,50)), Chat((50, 50),(50,50)),
]),
Layout([
Stream((100,60),(0,0)),
Stream((50,40),(0,60)), Stream((50, 40),(50,60)),
]),
Layout([
Stream((100,34),(0,0)),
Stream((100,33),(0,34)),
Stream((100,33),(0,67)),
]),
# 4 streams
Layout([
Stream((75,65),(0,0)), Chat((25,65),(75,0)),
Stream((33,35),(0,65)), Stream((34,35),(33,65)), Stream((33,35),(67,65)),
]),
Layout([
Stream((37,50),(0,0)), Stream((38,50),(37,0)), Chat((25,100),(75,0)),
Stream((37,50),(0,50)), Stream((38,50),(37,50)),
]),
Layout([
Stream((50,50),(0,0)), Stream((50,50),(50,0)),
Stream((50,50),(0,50)), Stream((50,50),(50,50)),
]),
Layout([
Stream((100,25),(0,0)),
Stream((100,25),(0,25)),
Stream((100,25),(0,50)),
Stream((100,25),(0,75)),
]),
# 5 Streams
Layout([
Stream((37,60),(0,0)), Stream((38,60),(37,0)), Chat((25,60),(75,0)),
Stream((33,40),(0,60)), Stream((34,40),(33,60)), Stream((33,40),(67,60)),
]),
Layout([
Stream((33,50),(0,0)), Stream((34,50),(33,0)), Stream((33,50),(67,0)),
Stream((33,50),(0,50)), Chat((34,50),(33,50)), Stream((33,50),(67,50)),
]),
Layout([
Stream((50,60),(0,0)), Stream((50,60),(50,0)),
Stream((33,40),(0,60)), Stream((34,40),(33,60)), Stream((33,40),(67,60)),
]),
# 6 Streams
Layout([
Stream((38,33),(0,0)), Stream((38,33),(38,0)), Chat((24,100),(76,0)),
Stream((38,34),(0,33)), Stream((38,34),(38,33)),
Stream((38,33),(0,67)), Stream((38,33),(38,67)),
]),
Layout([
Stream((33,50),(0,0)), Stream((34,50),(33,0)), Stream((33,50),(67,0)),
Stream((33,50),(0,50)), Stream((34,50),(33,50)), Stream((33,50),(67,50)),
]),
# 7 Streams!
Layout([
Stream((25,50),(0,0)), Stream((25,50),(25,0)), Stream((25,50),(50,0)), Stream((25,50),(75,0)),
Stream((25,50),(0,50)), Stream((25,50),(25,50)), Stream((25,50),(50,50)), Chat((25,50),(75,50)),
]),
Layout([
Stream((50,50),(25,0)), Chat((50,50),(25,50)),
Stream((25,33),(0,0)), Stream((25,34),(0,33)), Stream((25,33),(0,67)),
Stream((25,33),(75,0)), Stream((25,34),(75,33)), Stream((25,33),(75,67)),
]),
Layout([
Stream((33,60),(0,0)), Stream((34,60),(33,0)), Stream((33,60),(67,0)),
Stream((25,40),(0,60)), Stream((25,40),(25,60)), Stream((25,40),(50,60)), Stream((25,40),(75,60)),
]),
# 8 Streams !!
Layout([
Stream((33,33),(0,0)), Stream((34,33),(33,0)), Stream((33,33),(67,0)),
Stream((33,34),(0,33)), Stream((34,34),(33,33)), Stream((33,34),(67,33)),
Stream((33,33),(0,67)), Stream((34,33),(33,67)), Chat((33,33),(67,67)),
]),
Layout([
Stream((25,50),(0,0)), Stream((25,50),(25,0)), Stream((25,50),(50,0)), Stream((25,50),(75,0)),
Stream((25,50),(0,50)), Stream((25,50),(25,50)), Stream((25,50),(50,50)), Stream((25,50),(75,50)),
]),
]
LAYOUT_GROUPS = _initialize_layouts(STREAM_LAYOUTS)