Example #1
0
    def __init__(self, scroll):
        self._is_painting = False
        self._break_draw = False  # This variable indicates if should continuing drawing the widget or should move foward

        super(EventsWidget, self).__init__()
        self._scroll = scroll

        # Set the widget background to white ############################
        palette = self.palette()
        palette.setColor(self.backgroundRole(), QtCore.Qt.white)
        self.setPalette(palette)
        #################################################################

        self._max_time = 0
        self._tracks = []  # List of tracks
        self._pointer = Pointer(0, self, scroll)  # Timeline ( greenline )
        self.tracks_height = 30  # Height in pixels
        self.scale = conf.CONTROL_EVENTS_GRAPH_DEFAULT_SCALE
Example #2
0
	def __init__(self, scroll):
		self._is_painting = False
		self._break_draw = False  # This variable indicates if should continuing drawing the widget or should move foward

		super(EventsWidget, self).__init__()
		self._scroll = scroll

		# Set the widget background to white ############################
		palette = self.palette()
		palette.setColor(self.backgroundRole(), QtCore.Qt.white)
		self.setPalette(palette)
		#################################################################

		self._max_time = 0
		self._tracks = []      # List of tracks
		self._pointer = Pointer(0, self, scroll)  # Timeline ( greenline )
		self.tracks_height = 30                        # Height in pixels
		self.scale = conf.CONTROL_EVENTS_GRAPH_DEFAULT_SCALE
Example #3
0
class EventsWidget(QtGui.QWidget):
	"""
	Timeline widget definition to be used in the ControlEventTimeline
	"""

	_defautcolor = QtGui.QColor(100, 100, 255)

	def __init__(self, scroll):
		self._is_painting = False
		self._break_draw = False  # This variable indicates if should continuing drawing the widget or should move foward

		super(EventsWidget, self).__init__()
		self._scroll = scroll

		# Set the widget background to white ############################
		palette = self.palette()
		palette.setColor(self.backgroundRole(), QtCore.Qt.white)
		self.setPalette(palette)
		#################################################################

		self._max_time = 0
		self._tracks = []      # List of tracks
		self._pointer = Pointer(0, self, scroll)  # Timeline ( greenline )
		self.tracks_height = 30                        # Height in pixels
		self.scale = conf.CONTROL_EVENTS_GRAPH_DEFAULT_SCALE

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

	def clean(self):
		# Clean all events
		for track in self._tracks:
			track.clear()
		del self._tracks[:]
		self._tracks = []
		self._break_draw = True and self._is_painting
		self.repaint()

	def add_track(self, title=None):
		# Add a new track
		self._tracks.append(Track(parent=self))
		self.setMinimumHeight(self.which_top(len(self._tracks)))
		if title: self._tracks[-1].title = title
		return self._tracks[-1]

	def add_event(self, begin, end, title='', track=0, color="#FFFF00"):
		"""Adds an event."""

		period = Event(begin, end,
					   title=title,
					   parentWidget=self,
					   color=color
					   )

		if self._max_time < end:
			self._max_time = end
		# Create new tracks in case the variable track does not exists
		if len(self._tracks) <= track:
			for i in range(len(self._tracks), track + 1):
				t = self.add_track()
				t.title = title
		#################################################

		end_pixel = end / self._scale
		if end_pixel > self._scroll.maximum():
			self._scroll.setMaximum(end_pixel)

		self._tracks[track].add_period(period)
		return period

	def __check_current_time_is_visible(self, current_time):
		"""
		This function check if the current_time is visible to the user.
		"""

		scroll_limit = (self._scroll.sliderPosition() + self.width()) * self._scale

		if current_time > scroll_limit:
			self._scroll.setMaximum(current_time / self._scale)
			self._scroll.setSliderPosition(current_time / self._scale - self.width())
		if current_time < (self._scroll.sliderPosition() * self._scale):
			self._scroll.setSliderPosition(current_time / self._scale)

	def which_track(self, y):
		# Return the track index which collide with the Y coordenate
		return (y - 20) // self.tracks_height

	def which_top(self, track):
		# Return the Y coordenate where the track index start
		return track * self.tracks_height + 20

	##########################################################################
	#### DRAW FUNCTIONS ######################################################
	##########################################################################

	def paintEvent(self, e):
		self._is_painting = True
		super(EventsWidget, self).paintEvent(e)

		painter = QtGui.QPainter()
		painter.begin(self)
		painter.setRenderHint(QtGui.QPainter.Antialiasing)
		painter.setFont(QtGui.QFont('Decorative', 8))

		slider_pos = self._scroll.sliderPosition()
		start = slider_pos * self._scale
		end = start + self.width() * self._scale

		for i, track in enumerate(self._tracks):
			if self._break_draw:
				break
			track.draw_periods(painter, start, end, track_index=i, left_shift=-self._scroll.sliderPosition(), scale=self._scale)

		# Draw only from pixel start to end
		painter.setPen(QtCore.Qt.DashLine)
		painter.setOpacity(0.3)

		#print('Draw', start, end, self._scale, self._scroll.sliderPosition(), self.width())

		# Draw vertical lines
		for x in range(start - (start % (100 * self._scale)), end, 100 * self._scale):
			x2draw = (x - slider_pos * self._scale) // self._scale
			painter.drawLine(x2draw, 20, x2draw, self.height())
			string = str(x)
			boundtext = painter.boundingRect(QtCore.QRectF(), string)
			painter.drawText(x2draw - boundtext.width() / 2, 15, string)

		for index, track in enumerate(self._tracks):
			top = self.which_top(index)
			#print(top)
			painter.drawLine(0, top, self.width(), top)
			painter.drawText(10, top + 15, track.title)
		painter.setOpacity(1.0)

		self._pointer.draw(painter, left_shift=-slider_pos, scale=self._scale)  # Draw the time pointer
		painter.end()

		self._break_draw = False
		self._is_painting = False

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

	@property
	def scale(self): return self._scale

	@scale.setter
	def scale(self, value):
		self._scale = value
		self._scroll.setMaximum(self._max_time / self._scale)

	@property
	def scroll(self): return self._scroll

	@property
	def position(self): return self._pointer._position

	@position.setter
	def position(self, position):
		self._pointer._position = position
		self._break_draw = True and self._is_painting

		if (position / self._scale) >= sys.maxsize:
			self.scale += 1

		#######################################################################
		# Check if the current time position is inside the scroll
		# if is not in, update the scroll position
		self.__check_current_time_is_visible(position)
		#######################################################################
		self.repaint()

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

	@color.setter
	def color(self, value): self._defautcolor = value

	@property
	def tracks_height(self): return self._tracks_height

	@tracks_height.setter
	def tracks_height(self, value):
		self._tracks_height = value
		new_height = len(self.tracks) * value + 20
		if new_height > self.height():
			self.setMinimumHeight(new_height)
		self._break_draw = True and self._is_painting
		self.repaint()

	@property
	def tracks(self): return self._tracks

	##########################################################################
	#### IMPORT AND EXPORT DATA ##############################################
	##########################################################################

	def import_csv(self, csvfileobject):
		"""
		Extracts info from a file object and stores it in memory in
		order to display it on the timeline.

		Refer to the `export` method to learn about input file format
		and structure.
		"""
		# Clear previously stored info
		self._tracks = []
		self._selected = None

		for row in csvfileobject:
			if row[0] == "T":
				track = self.add_track()
				track.properties = row
			elif row[0] == "P":
				event = self.add_event(0, 1, '-')
				event.properties = row

	def export_csv(self, csvfileobject):
		"""
		Processes all timeline data in an arranged format to be written
		in a CSV file.


		Current file structure:
		=======================

		--- CSV FILE BEGIN ---
		Track info line
		Event info line
		Event info line
		...
		Track info line
		Event info line
		Event info line
		...
		Track info line
		Event info line
		Event info line
		...
		--- CSV FILE END ---


		Track info line format:
		=======================

		| T | Total # of events in this track |  |  | Color | Label |


		Event info line format:
		=======================

		| P | Lock status | Begin frame | End frame | Comment | Color |  |
		"""
		for index, track in enumerate(self._tracks):
			csvfileobject.writerow(track.properties)
			for delta in track.periods:
				csvfileobject.writerow(delta.properties)
Example #4
0
class EventsWidget(QtGui.QWidget):
    """
    Timeline widget definition to be used in the ControlEventTimeline
    """

    _defautcolor = QtGui.QColor(100, 100, 255)

    def __init__(self, scroll):
        self._is_painting = False
        self._break_draw = False  # This variable indicates if should continuing drawing the widget or should move foward

        super(EventsWidget, self).__init__()
        self._scroll = scroll

        # Set the widget background to white ############################
        palette = self.palette()
        palette.setColor(self.backgroundRole(), QtCore.Qt.white)
        self.setPalette(palette)
        #################################################################

        self._max_time = 0
        self._tracks = []  # List of tracks
        self._pointer = Pointer(0, self, scroll)  # Timeline ( greenline )
        self.tracks_height = 30  # Height in pixels
        self.scale = conf.CONTROL_EVENTS_GRAPH_DEFAULT_SCALE

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

    def clean(self):
        # Clean all events
        for track in self._tracks:
            track.clear()
        del self._tracks[:]
        self._tracks = []
        self._break_draw = True and self._is_painting
        self.repaint()

    def add_track(self):
        # Add a new track
        self._tracks.append(Track(parent=self))
        self.setMinimumHeight(self.which_top(len(self._tracks)))
        return self._tracks[-1]

    def add_event(self, begin, end, title='', track=0, color="#FFFF00"):
        """Adds an event."""

        period = Event(begin, end, title=title, parentWidget=self, color=color)

        if self._max_time < end:
            self._max_time = end
        # Create new tracks in case the variable track does not exists
        if len(self._tracks) <= track:
            for i in range(len(self._tracks), track + 1):
                t = self.add_track()
                t.title = title
        #################################################

        end_pixel = end / self._scale
        if end_pixel > self._scroll.maximum():
            self._scroll.setMaximum(end_pixel)

        self._tracks[track].add_period(period)
        return period

    def __check_current_time_is_visible(self, current_time):
        """
        This function check if the current_time is visible to the user.
        """

        scroll_limit = (self._scroll.sliderPosition() +
                        self.width()) * self._scale

        if current_time > scroll_limit:
            self._scroll.setMaximum(current_time / self._scale)
            self._scroll.setSliderPosition(current_time / self._scale -
                                           self.width())
        if current_time < (self._scroll.sliderPosition() * self._scale):
            self._scroll.setSliderPosition(current_time / self._scale)

    def which_track(self, y):
        # Return the track index which collide with the Y coordenate
        return (y - 20) // self.tracks_height

    def which_top(self, track):
        # Return the Y coordenate where the track index start
        return track * self.tracks_height + 20

    ##########################################################################
    #### DRAW FUNCTIONS ######################################################
    ##########################################################################

    def paintEvent(self, e):
        self._is_painting = True
        super(EventsWidget, self).paintEvent(e)

        painter = QtGui.QPainter()
        painter.begin(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setFont(QtGui.QFont('Decorative', 8))

        slider_pos = self._scroll.sliderPosition()
        start = slider_pos * self._scale
        end = start + self.width() * self._scale

        for i, track in enumerate(self._tracks):
            if self._break_draw:
                break
            track.draw_periods(painter,
                               start,
                               end,
                               track_index=i,
                               left_shift=-self._scroll.sliderPosition(),
                               scale=self._scale)

        # Draw only from pixel start to end
        painter.setPen(QtCore.Qt.DashLine)
        painter.setOpacity(0.3)

        #print('Draw', start, end, self._scale, self._scroll.sliderPosition(), self.width())

        # Draw vertical lines
        for x in range(start - (start % (100 * self._scale)), end,
                       100 * self._scale):
            x2draw = (x - slider_pos * self._scale) // self._scale
            painter.drawLine(x2draw, 20, x2draw, self.height())
            string = str(x)
            boundtext = painter.boundingRect(QtCore.QRectF(), string)
            painter.drawText(x2draw - boundtext.width() / 2, 15, string)

        for index, track in enumerate(self._tracks):
            top = self.which_top(index)
            painter.drawLine(0, top, self.width(), top)
            painter.drawText(10, top + 15, track.title)
        painter.setOpacity(1.0)

        self._pointer.draw(painter, left_shift=-slider_pos,
                           scale=self._scale)  # Draw the time pointer
        painter.end()

        self._break_draw = False
        self._is_painting = False

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

    @property
    def scale(self):
        return self._scale

    @scale.setter
    def scale(self, value):
        self._scale = value
        self._scroll.setMaximum(self._max_time / self._scale)

    @property
    def scroll(self):
        return self._scroll

    @property
    def position(self):
        return self._pointer._position

    @position.setter
    def position(self, position):
        self._pointer._position = position
        self._break_draw = True and self._is_painting

        if (position / self._scale) >= sys.maxsize:
            self.scale += 1

        #######################################################################
        # Check if the current time position is inside the scroll
        # if is not in, update the scroll position
        self.__check_current_time_is_visible(position)
        #######################################################################
        self.repaint()

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

    @color.setter
    def color(self, value):
        self._defautcolor = value

    @property
    def tracks_height(self):
        return self._tracks_height

    @tracks_height.setter
    def tracks_height(self, value):
        self._tracks_height = value
        new_height = len(self.tracks) * value + 20
        if new_height > self.height():
            self.setMinimumHeight(new_height)
        self._break_draw = True and self._is_painting
        self.repaint()

    @property
    def tracks(self):
        return self._tracks

    ##########################################################################
    #### IMPORT AND EXPORT DATA ##############################################
    ##########################################################################

    def import_csv(self, csvfileobject):
        """
        Extracts info from a file object and stores it in memory in
        order to display it on the timeline.

        Refer to the `export` method to learn about input file format
        and structure.
        """
        # Clear previously stored info
        self._tracks = []
        self._selected = None

        for row in csvfileobject:
            if row[0] == "T":
                track = self.add_track()
                track.properties = row
            elif row[0] == "P":
                event = self.add_event(0, 1, '-')
                event.properties = row

    def export_csv(self, csvfileobject):
        """
        Processes all timeline data in an arranged format to be written
        in a CSV file.


        Current file structure:
        =======================

        --- CSV FILE BEGIN ---
        Track info line
        Event info line
        Event info line
        ...
        Track info line
        Event info line
        Event info line
        ...
        Track info line
        Event info line
        Event info line
        ...
        --- CSV FILE END ---


        Track info line format:
        =======================

        | T | Total # of events in this track |  |  | Color | Label |


        Event info line format:
        =======================

        | P | Lock status | Begin frame | End frame | Comment | Color |  |
        """
        for index, track in enumerate(self._tracks):
            csvfileobject.writerow(track.properties)
            for delta in track.periods:
                csvfileobject.writerow(delta.properties)