Package Gnumed :: Package timelinelib :: Package canvas :: Package data :: Module timeperiod
[frames] | no frames]

Source Code for Module Gnumed.timelinelib.canvas.data.timeperiod

1 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Rickard Lindberg, Roger Lindberg 2 # 3 # This file is part of Timeline. 4 # 5 # Timeline is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as published by 7 # the Free Software Foundation, either version 3 of the License, or 8 # (at your option) any later version. 9 # 10 # Timeline is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with Timeline. If not, see <http://www.gnu.org/licenses/>. 17 18 19 -class TimePeriod(object):
20 21 """ 22 Represents a period in time using a start and end time. 23 24 This is used both to store the time period for an event and for storing the 25 currently displayed time period in the GUI. 26 """ 27
28 - def __init__(self, start_time, end_time):
29 self._start_time, self._end_time = self._update(start_time, end_time)
30 31 @property
32 - def start_time(self):
33 return self._start_time
34 35 @property
36 - def end_time(self):
37 return self._end_time
38 39 @property
40 - def start_and_end_time(self):
41 return self._start_time, self._end_time
42
43 - def __eq__(self, other):
44 return (isinstance(other, TimePeriod) and 45 self.start_time == other.start_time and 46 self.end_time == other.end_time)
47
48 - def __ne__(self, other):
49 return not (self == other)
50
51 - def __repr__(self):
52 return "TimePeriod<%s, %s>" % (self.start_time, self.end_time)
53
54 - def get_time_at_percent(self, percent):
55 return self.start_time + self.delta() * percent
56
57 - def get_start_time(self):
58 return self.start_time
59
60 - def get_end_time(self):
61 return self.end_time
62
63 - def set_start_time(self, time):
64 return self.update(time, self.end_time)
65
66 - def set_end_time(self, time):
67 return self.update(self.start_time, time)
68
69 - def start_to_start(self, time_period):
71
72 - def start_to_end(self, time_period):
74
75 - def end_to_start(self, time_period):
77
78 - def end_to_end(self, time_period):
80
81 - def update(self, start_time, end_time, 82 start_delta=None, end_delta=None):
83 new_start, new_end = self._update(start_time, end_time, start_delta, end_delta) 84 return TimePeriod(new_start, new_end)
85
86 - def _update(self, start_time, end_time, start_delta=None, end_delta=None):
87 """ 88 Change the time period data. 89 90 Optionally add the deltas to the times like this: time + delta. 91 92 If data is invalid, it will not be set, and a ValueError will be raised 93 instead. Data is invalid if or if the start time is larger than the end 94 time. 95 """ 96 new_start = self._calc_new_time(start_time, start_delta) 97 new_end = self._calc_new_time(end_time, end_delta) 98 self._assert_period_is_valid(new_start, new_end) 99 return (new_start, new_end)
100
101 - def _assert_period_is_valid(self, new_start, new_end):
102 if new_start is None: 103 raise ValueError(_("Invalid start time")) 104 if new_end is None: 105 raise ValueError(_("Invalid end time")) 106 if new_start > new_end: 107 raise ValueError(_("Start time can't be after end time. Start:%s End:%s" % 108 (new_start.to_str(), new_end.to_str())))
109
110 - def inside(self, time):
111 """ 112 Return True if the given time is inside this period or on the border, 113 otherwise False. 114 """ 115 return time >= self.start_time and time <= self.end_time
116
117 - def distance_to(self, time_period):
118 if time_period.starts_after(self.end_time): 119 return self.end_to_start(time_period).delta() 120 elif time_period.ends_before(self.start_time): 121 return time_period.end_to_start(self).delta() 122 else: 123 return None
124
125 - def overlaps(self, time_period):
128
129 - def outside_period(self, time_period):
132
133 - def inside_period(self, time_period):
134 return not self.outside_period(time_period)
135
136 - def starts_after(self, time):
137 return self.start_time > time
138
139 - def starts_before(self, time):
140 return self.start_time < time
141
142 - def ends_before(self, time):
143 return self.end_time < time
144
145 - def ends_after(self, time):
146 return self.end_time > time
147
148 - def ends_at(self, time):
149 return self.end_time == time
150
151 - def is_period(self):
152 """ 153 Return True if this time period is longer than just a point in time, 154 otherwise False. 155 """ 156 return self.start_time != self.end_time
157
158 - def mean_time(self):
159 """ 160 Return the time in the middle if this time period is longer than just a 161 point in time, otherwise the point in time for this time period. 162 """ 163 return self.start_time + (self.delta() / 2)
164
165 - def zoom(self, times, ratio=0.5):
166 start_delta = self.delta() * (times * ratio / 5.0) 167 end_delta = self.delta() * (-times * (1.0 - ratio) / 5.0) 168 return self.update(self.start_time, self.end_time, start_delta, end_delta)
169
170 - def move(self, direction):
171 """ 172 Move this time period one 10th to the given direction. 173 174 Direction should be -1 for moving to the left or 1 for moving to the 175 right. 176 """ 177 delta = self.delta() * (direction / 10.0) 178 return self.move_delta(delta)
179
180 - def move_delta(self, delta):
181 return self.update(self.start_time, self.end_time, delta, delta)
182
183 - def delta(self):
184 """Return the length of this time period as a timedelta object.""" 185 return self.end_time - self.start_time
186
187 - def center(self, time):
188 return self.move_delta(time - self.mean_time())
189
190 - def _calc_new_time(self, time, delta):
191 if delta is None: 192 return time 193 return time + delta
194
195 196 -class TimeOutOfRangeLeftError(ValueError):
197 pass
198
199 200 -class TimeOutOfRangeRightError(ValueError):
201 pass
202
203 204 -def time_period_center(time, length):
205 """ 206 TimePeriod factory method. 207 208 Return a time period with the given length (represented as a timedelta) 209 centered around `time`. 210 """ 211 half_length = length * 0.5 212 start_time = time - half_length 213 end_time = time + half_length 214 return TimePeriod(start_time, end_time)
215