Ejemplo n.º 1
0
class TimelineDelta(object):
    """
	
	"""
    def __init__(self,
                 begin,
                 end=30,
                 title=None,
                 height=30,
                 top=0,
                 parent=None):
        """
		
		:param begin: 
		:param end: 
		:param title: 
		:param height: 
		:param top: 
		:param parent: 
		"""
        self._top = top
        self._height = height
        self._parent = parent
        self._title = title
        self._lock = False
        self._begin = begin
        self._end = end

        self.checkNumberOfTracks()

        self._defautcolor = parent._tracks[self.track].color

    ##########################################################################
    #### HELPERS/FUNCTIONS ###################################################
    ##########################################################################

    def checkNumberOfTracks(self):
        """
		
		:return: 
		"""
        if self.track >= (self._parent.numberoftracks - 1):
            for i in range(self._parent.numberoftracks - 1, self.track + 1):
                self._parent.add_track()

    def collide(self, x, y):
        """
		
		:param x: 
		:param y: 
		:return: 
		"""
        return self.begin <= x <= self.end and self._top <= y <= (self._top +
                                                                  self._height)

    def in_range(self, start, end):
        """
		:param start: 
		:param end: 
		:return: 
		"""
        return start <= self.begin and end >= self.end or \
            self.begin <= start <= self.end or \
            self.begin <= end <= self.end

    def canSlideBegin(self, x, y):
        """
		
		:param x: 
		:param y: 
		:return: 
		"""
        begin = int(round(self.begin))
        end = int(round(self.end))
        return not self._lock and begin <= x <= (
            begin + 10) and self._top <= y <= (self._top + self._height) and (
                x - end)**2 > (x - begin)**2

    def canSlideEnd(self, x, y):
        """
		
		:param x: 
		:param y: 
		:return: 
		"""
        begin = int(round(self.begin))
        end = int(round(self.end))
        #check if the delta is not locked
        #check if the x is inside an range of 10 pixels
        #check if the y is within the boundaries of the delta
        return not self._lock and (
            end - 10) <= x <= end and self._top <= y <= (
                self._top + self._height) and (x - end)**2 < (x - begin)**2

    def moveEnd(self, x):
        """
		Move the right edge of the event rectangle.
		:param x: 
		"""
        jump = x / self._parent._scale

        # Do nothing if locked
        if self._lock:
            return

        # Do nothing if trying to go over the pther edge
        if (self._end + jump) <= self._begin and jump < 0:
            return

        # Increment accordingly
        self._end += jump

        # Minimum begin position is at 0
        if self._end > (self._parent.width() / self._parent._scale):
            self._end = (self._parent.width() / self._parent._scale)

    def moveBegin(self, x):
        """
		Move the left edge of the event rectangle.
		:param x: 
		"""
        jump = x / self._parent._scale

        # Do nothing if locked
        if self._lock:
            return

        # Do nothing if trying to go over the other edge
        if (self._begin + jump) >= self._end and jump > 0:
            return

        # Increment accordingly
        self._begin += jump

        # Minimum begin position is at 0
        if self._begin < 0: self._begin = 0

    def move(self, x, y):
        """
		
		:param x: 
		:param y: 
		:return: 
		"""
        if self._lock: return

        if (self.begin + x) >= 0 and (self.end + x) <= self._parent.width():
            self._begin += x / self._parent._scale
            self._end += x / self._parent._scale
        current_track = self.track
        new_track = Track.whichTrack(y)

        if current_track != new_track and new_track >= 0 and new_track <= self._parent.numberoftracks:
            self.track = new_track
            self.checkNumberOfTracks()

    def showEditWindow(self):
        """
		
		:return: 
		"""
        """
		text, ok = QInputDialog.getText(
			self._parent, 'Edit event', 'Comment:', text=self._title)
		"""
        if hasattr(self, 'edit_form'):
            self.edit_form.comment = self._title
            self.edit_form.begin = self._begin
            self.edit_form.end = self._end
            self.edit_form.show()
        else:
            self.edit_form = DeltaEditWindow(self._parent, self._title,
                                             self._begin, self._end)
            self.edit_form.apply_function = self.__apply_changes
            self.edit_form.show()

    def __apply_changes(self):
        self._title = self.edit_form.comment
        self._begin = self.edit_form.begin
        self._end = self.edit_form.end
        self._parent.repaint()
        self.edit_form.hide()

    def draw(self, painter, showvalues=False):
        """
		
		:param painter: 
		:param showvalues: 
		:return: 
		"""
        start, end = self.begin, self.end
        if self._lock:
            transparency = 0.1
        else:
            transparency = 0.5
        painter.setPen(QColor(0, 0, 0))
        painter.setOpacity(transparency)
        painter.drawRoundedRect(start, self._top, end - start, self._height, 3,
                                3)
        painter.setOpacity(1.0)

        painter.drawText(start + 3, self._top + 19, self._title)
        if showvalues:
            painter.drawText(
                start, self._top + 44, "[%d;%d] delta:%d" %
                (self._begin, self._end, self._end - self._begin))

    def remove(self):
        """
		
		:return: 
		"""
        try:
            self._parent._tracks[self.track].periods.remove(self)
        except:
            pass

    ##########################################################################
    #### PROPERTIES ##########################################################
    ##########################################################################

    @property
    def title(self):
        return self._title

    @property
    def lock(self):
        return self._lock

    @lock.setter
    def lock(self, value):
        self._lock = value

    @property
    def begin(self):
        return self._begin * self._parent._scale

    @begin.setter
    def begin(self, value):
        if self._lock: return
        self._begin = value / self._parent._scale
        if self._begin < 0: self._begin = 0

    @property
    def end(self):
        return self._end * self._parent._scale

    @end.setter
    def end(self, value):
        if self._lock: return
        self._end = value / self._parent._scale
        if self._end > (self._parent.width() / self._parent._scale):
            self._end = (self._parent.width() / self._parent._scale)

    @property
    def track(self):
        return Track.whichTrack(self._top)

    @track.setter
    def track(self, value):
        # if the object exists in other track remove it
        if self.track < len(
                self._parent._tracks) and self in self._parent._tracks[
                    self.track].periods:
            self.remove()

        # Verify if the new track exists. In case not create it
        self._top = Track.whichTop(value)
        if self.track >= len(self._parent._tracks): self._parent.add_track()

        # if do not exists in the track add it
        if self not in self._parent._tracks[self.track].periods:
            self._parent._tracks[self.track].periods.append(self)

    @property
    def color(self):
        return self._defautcolor

    @color.setter
    def color(self, value):
        self._defautcolor = QColor(value) if (type(value) == str) else value

    @property
    def bgrcolor(self):
        return self._defautcolor.blue(), self._defautcolor.green(
        ), self._defautcolor.red()

    @property
    def properties(self):
        return [
            'P', self._lock,
            int(round(self._begin)),
            int(round(self._end)), self._title,
            self._defautcolor.name(), self.track
        ]

    @properties.setter
    def properties(self, value):
        self._lock = value[1] == 'True'
        self._begin = int(value[2])
        self._end = int(value[3])
        self._title = value[4]
        self._defautcolor = QColor(value[5])
        self.track = int(value[6])

        self.checkNumberOfTracks()
Ejemplo n.º 2
0
class Event(object):
    """
	Class representing a time period \ event.
	"""
    def __init__(self,
                 begin,
                 end=30,
                 title=None,
                 lock=False,
                 color=None,
                 track=None,
                 widget=None):
        """
		Constructor
		
		:param int begin: First frame
		:param int end: Last frame
		:param str title: Event title
		:param bool lock: Flag to set the event lock
		:param AnyQt.QtGui.QColor color: Color of the event
		:param Track track: Track to witch the period will be added
		:param TimelineWidget widget: Parent timeline widget
		"""
        self._track = track
        self._widget = widget
        self._title = title
        self._lock = lock
        self._begin = begin
        self._end = end
        self._end = end
        self._color = track.color if color is None else color

        track += self

    ##########################################################################
    #### HELPERS/FUNCTIONS ###################################################
    ##########################################################################

    def collide(self, xcoord, ycoord):
        """
		Check if the x,y coordinate collides with the time period
		:param int xcoord: X coordinate in pixels.
		:param int ycoord: Y coordinate in pixels.
		:return: True if collide, False otherwise.
		"""
        return self.begin_coordinate <= xcoord <= self.end_coordinate and self.top_coordinate <= ycoord <= self.bottom_coordinate

    def in_range(self, start, end):
        """
		Check if the period is within the limits [start;end]
		:param int start: Initial X coordinate
		:param int end: Final X coordinate
		:return: True if in range, False otherwise
		"""
        return start <= self.begin_coordinate and end >= self.end_coordinate or \
            self.begin_coordinate <= start <= self.end_coordinate or \
            self.begin_coordinate <= end <= self.end_coordinate

    def can_slide_begin(self, xcoord, ycoord):
        """
		Checks if xcoord and ycoord pixel coordinate can slide the beginning of the period.
		:param int xcoord: X coordinate in pixels.
		:param int ycoord: Y coordinate in pixels.
		:return boolean: True if the event can be slided, false if not.
		"""
        # if locked does nothing
        if self._lock: return

        begin = int(round(self.begin_coordinate))
        end = int(round(self.end_coordinate))
        return begin <= xcoord <= (begin+10) and \
            self.top_coordinate <= ycoord <= self.bottom_coordinate and \
            (xcoord-end)**2 > (xcoord-begin)**2

    def can_slide_end(self, x, y):
        """
		Checks if x,y pixel coordinate can slide the end of the period.
		:param int x: X coordinate in pixels.
		:param int y: Y coordinate in pixels.
		:return boolean: True if the event can be slided, false if not.
		"""
        # if locked does nothing
        if self._lock: return

        begin = int(round(self.begin))
        end = int(round(self.end))
        #check if the delta is not locked
        #check if the x is inside an range of 10 pixels
        #check if the y is within the boundaries of the delta
        return not self._lock and \
           (end-10) <= x <= end and \
           self.top_coordinate <= y <= self.bottom_coordinate and \
           (x-end)**2 < (x-begin)**2

    def move_end(self, xdelta):
        """
		Move the right edge of the period rectangle.
		:param int xdelta: X delta coordinate in pixels to move
		"""
        # Do nothing if locked
        if self._lock: return

        jump = xdelta / self._widget.scale

        # Do nothing if trying to go over the pther edge
        if (self.end_coordinate + jump) <= self.begin_coordinate and jump < 0:
            return

        # Increment accordingly
        self._end += jump

        # Minimum begin position is at 0
        if self._end > (self._widget.width() / self._widget.scale):
            self._end = (self._widget.width() / self._widget.scale)

    def move_begin(self, xcoord):
        """
		Move the left edge of the period rectangle.
		:param int xdelta: X delta coordinate in pixels to move
		"""
        # Do nothing if locked
        if self._lock: return

        jump = xcoord / self._widget.scale

        # Do nothing if trying to go over the other edge
        if (self._begin + jump) >= self._end and jump > 0:
            return

        # Increment accordingly
        self._begin += jump

        # Minimum begin position is at 0
        if self._begin < 0: self._begin = 0

    def move(self, xdelta, ycoord):
        """
		Move the event period more X and Y coordinates
		:param int xdelta: X delta to move in pixels
		:param int ycoord: Y coordinate to which the period should be moved
		"""
        # The period is locked, do nothing.
        if self._lock: return

        # if the new positions are within the 0 and maximum position,
        # then update the period positions
        if  (self.begin_coordinate + xdelta) >= 0 and \
         (self.end_coordinate + xdelta) <= self._widget.width():
            # update the positions
            delta = xdelta / self._widget.scale
            self._begin += delta
            self._end += delta

        if not (self.track.bottom_coordinate <= ycoord <=
                self.track.top_coordinate):
            self.track = self._widget.find_track(ycoord)

    def draw(self, painter, showvalues=False):
        """
		
		:param painter: 
		:param showvalues: 
		:return: 
		"""
        start, end = self.begin_coordinate, self.end_coordinate
        transparency = 0.1 if self._lock else 0.5

        painter.setPen(QColor(0, 0, 0))
        painter.setOpacity(transparency)
        painter.drawRoundedRect(start, self.top_coordinate, end - start,
                                self._widget.EVENT_HEIGHT, 3, 3)

        painter.setOpacity(1.0)
        painter.drawText(
            start + 3, self.top_coordinate + self._widget.EVENT_TITLE_TOP_POS,
            self.title)
        if showvalues:
            painter.drawText(
                start, self.top_coordinate + self._widget.EVENT_RANGE_TOP_POS,
                "[{};{}] delta:{}".format(
                    int(self.begin_coordinate), int(self.end_coordinate),
                    int(self.end_coordinate - self.begin_coordinate)))

    def remove(self):
        """
		Remove the period from the tracks
		"""
        self.track = None

    def open_properties(self):
        """
		Open the properties window
		"""
        if hasattr(self, 'edit_form'):
            self.edit_form.update_form(self)
        else:
            self.edit_form = EventWindow(self._widget, self)

        self.edit_form.show()

    def __apply_properties_evt(self):
        """
		Event called to apply the properties values in the Perido window
		:return:
		"""
        self._title = self.edit_form.comment
        self._begin = self.edit_form.begin
        self._end = self.edit_form.end
        self._widget.repaint()
        self.edit_form.hide()

    ##########################################################################
    #### PROPERTIES ##########################################################
    ##########################################################################

    @property
    def title(self):
        return self._title

    @title.setter
    def title(self, value):
        self._title = value

    @property
    def lock(self):
        return self._lock

    @lock.setter
    def lock(self, value):
        self._lock = value

    @property
    def begin(self):
        return self._begin

    @begin.setter
    def begin(self, value):
        self._begin = value

    @property
    def end(self):
        return self._end

    @end.setter
    def end(self, value):
        self._end = value

    @property
    def track(self):
        """
		:return: The current track
		"""
        return self._track

    @track.setter
    def track(self, value):
        """
		Set the current track.
		:param value:
		"""
        # check if the new track is different from the previous.
        # if so update the tracks events lists
        if self._track != value:
            self._track -= self

            if value is not None:
                value += self

        self._track = value

    @property
    def top_coordinate(self):
        return self._track.top_coordinate + 2

    @property
    def bottom_coordinate(self):
        return self._track.bottom_coordinate - 2

    @property
    def begin_coordinate(self):
        return self._begin * self._widget.scale

    @begin_coordinate.setter
    def begin_coordinate(self, value):
        if self._lock: return
        self._begin = value / self._widget.scale
        if self._begin < 0: self._begin = 0

    @property
    def end_coordinate(self):
        return self._end * self._widget.scale

    @end_coordinate.setter
    def end_coordinate(self, value):
        if self._lock: return
        self._end = value / self._widget.scale
        if self._end > (self._widget.width() / self._widget.scale):
            self._end = (self._widget.width() / self._widget.scale)

    @property
    def color(self):
        return self._color

    @color.setter
    def color(self, value):
        self._color = QColor(value) if (type(value) == str) else value

    @property
    def bgrcolor(self):
        return self._color.blue(), self._color.green(), self._color.red()

    @property
    def properties(self):
        return [
            'P', self._lock,
            int(round(self._begin)),
            int(round(self._end)), self._title,
            self._color.name(), self.track
        ]

    @properties.setter
    def properties(self, value):
        self._lock = value[1] == 'True'
        self._begin = int(value[2])
        self._end = int(value[3])
        self._title = value[4]
        self._color = QColor(value[5])
        self.track = int(value[6])

        self.checkNumberOfTracks()