summary refs log tree commit diff stats
path: root/ranger/gui/bar.py
blob: 5755039906755c1a65fab78b353a1835bf18e992 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class Bar(object):
	left = None
	right = None
	gap = None

	def __init__(self, base_color_tag):
		self.left = BarSide(base_color_tag)
		self.right = BarSide(base_color_tag)
		self.gap = BarSide(base_color_tag)

	def add(self, *a, **kw):
		self.left.add(*a, **kw)
	
	def addright(self, *a, **kw):
		self.right.add(*a, **kw)
	
	def sumsize(self):
		return self.left.sumsize() + self.right.sumsize()

	def fixedsize(self):
		return self.left.fixedsize() + self.right.fixedsize()

	def shrink_by_removing(self, wid):
		leftsize = self.left.sumsize()
		rightsize = self.right.sumsize()
		sumsize = leftsize + rightsize

		# remove elemets from the left until it fits
		if sumsize > wid:
			while len(self.left) > 0:
				leftsize -= len(self.left.pop(-1).string)
				if leftsize + rightsize <= wid:
					break
			sumsize = leftsize + rightsize

			# remove elemets from the right until it fits
			if sumsize > wid:
				while len(self.right) > 0:
					rightsize -= len(self.right.pop(0).string)
					if leftsize + rightsize <= wid:
						break
				sumsize = leftsize + rightsize

		if sumsize < wid:
			self.fill_gap(' ', (wid - sumsize), gapwidth=True)
	
	def shrink_by_cutting(self, wid):
		fixedsize = self.fixedsize()
		if wid < fixedsize:
			raise ValueError("Cannot shrink down to that size by cutting")

		leftsize = self.left.sumsize()
		rightsize = self.right.sumsize()
		nonfixed_items = self.left.nonfixed_items()

		itemsize = int(float(wid - rightsize - fixedsize) / nonfixed_items) + 1

		for item in self.left:
			if not item.fixed:
				item.cut_off_to(itemsize)

		self.fill_gap(' ', wid, gapwidth=False)

	def fill_gap(self, char, wid, gapwidth=False):
		del self.gap[:]

		if not gapwidth:
			wid = wid - self.sumsize()

		if wid > 0:
			self.gap.add(char * wid, 'space')
	
	def combine(self):
		return self.left + self.gap + self.right


class BarSide(list):
	def __init__(self, base_color_tag):
		self.base_color_tag = base_color_tag

	def add(self, string, *lst, **kw):
		cs = ColoredString(string, self.base_color_tag, *lst)
		if 'fixedsize' in kw:
			cs.fixed = kw['fixedsize']
		self.append(cs)
	
	def add_space(self, n=1):
		self.add(' ' * n, 'space')
	
	def sumsize(self):
		return sum(len(item) for item in self)

	def fixedsize(self):
		n = 0
		for item in self:
			if item.fixed:
				n += len(item)
			else:
				n += 1
		return n
	
	def nonfixed_items(self):
		return sum(1 for item in self if not item.fixed)


class ColoredString(object):
	fixed = False

	def __init__(self, string, *lst):
		self.string = string
		self.lst = lst
	
	def cut_off(self, n):
		n = max(n, min(len(self.string), 1))
		self.string = self.string[:-n]

	def cut_off_to(self, n):
		self.string = self.string[:n]
	
	def __len__(self):
		return len(self.string)

	def __str__(self):
		return self.string