예제 #1
0
void Layout::draw(QPainter* painter, float width, float height)
{
	if (hasBackgroundColor())
		painter->fillRect(0, 0, width, height, getBackgroundColor());
	if (background_image)
	{
		if (width == background_image->width() && height == background_image->height())
			painter->drawPixmap(QRectF(0, 0, width, height), *background_image, QRectF(0, 0, background_image->width(), background_image->height()));
		else
		{
			if (!background_image_cache || background_image_cache->width() != width || background_image_cache->height() != height)
			{
				delete background_image_cache;
				background_image_cache = new QPixmap(width, height);
				
				QPainter cache_painter(background_image_cache);
				cache_painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
				cache_painter.drawPixmap(QRectF(0, 0, width, height), *background_image, QRectF(0, 0, background_image->width(), background_image->height()));
				cache_painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
			}
		
			painter->drawPixmap(QRectF(0, 0, width, height), *background_image_cache, QRectF(0, 0, background_image_cache->width(), background_image_cache->height()));
		}
	}
	
	for (std::map<QString, Point*>::iterator it = points.begin(); it != points.end(); ++it)
	{
		Point* point = it->second;
		
		Font* font_data = point->strong_font ? point->font_strong : point->font_normal;
		QFont font = qFontFromFont(font_data, height);
		QFontMetricsF font_metrics(font);
		
		// NOTE: Could optimize this by caching the size
		float text_width = font_metrics.width(point->text);
		float text_height = font_metrics.height();	// TODO: Count lines
		
		QRectF rect = QRectF(point->pos.x()*width - 0.5f*text_width, point->pos.y()*height - 0.5f*text_height, text_width, text_height);
		Qt::Alignment alignment = point->alignment;
		if (point->alignment & Qt::AlignLeft)
			rect.translate(0.5f*text_width, 0);
		else if (point->alignment & Qt::AlignRight)
			rect.translate(-0.5f*text_width, 0);
		if (point->alignment & Qt::AlignTop)
			rect.translate(0, 0.5f*text_height);
		else if (point->alignment & Qt::AlignBottom)
			rect.translate(0, -0.5f*text_height);
		else if (point->alignment & Qt::AlignAbsolute)
		{
			rect.translate(0, 0.5f*text_height - font_metrics.ascent());
			alignment = (alignment & ~Qt::AlignAbsolute) | Qt::AlignVCenter;
		}
		
		painter->setFont(font);
		painter->setPen(font_data->color);
		
		if (point->max_width > 0)
			painter->drawText(rect, alignment, font_metrics.elidedText(point->text, Qt::ElideMiddle, point->max_width*width));
		else
			painter->drawText(rect, alignment, point->text);
	}
}
예제 #2
0
void PlaylistView::paintEvent(QPaintEvent* event) {
  // Reimplemented to draw the background image.
  // Reimplemented also to draw the drop indicator
  // When the user is dragging some stuff over the playlist paintEvent gets
  // called for the entire viewport every time the user moves the mouse.
  // The drawTree is kinda expensive, so we cache the result and draw from the
  // cache while the user is dragging.  The cached pixmap gets invalidated in
  // dragLeaveEvent, dropEvent and scrollContentsBy.

  // Draw background
  if (background_image_type_ == Custom ||
      background_image_type_ == AlbumCover) {
    if (!background_image_.isNull() || !previous_background_image_.isNull()) {
      QPainter background_painter(viewport());

      // Check if we should recompute the background image
      if (height() != last_height_ || width() != last_width_ ||
          force_background_redraw_) {
        if (background_image_.isNull()) {
          cached_scaled_background_image_ = QPixmap();
        } else {
          cached_scaled_background_image_ =
              QPixmap::fromImage(background_image_.scaled(
                  width(), height(), Qt::KeepAspectRatioByExpanding,
                  Qt::SmoothTransformation));
        }

        last_height_ = height();
        last_width_ = width();
        force_background_redraw_ = false;
      }

      // Actually draw the background image
      if (!cached_scaled_background_image_.isNull()) {
        // Set opactiy only if needed, as this deactivate hardware acceleration
        if (!qFuzzyCompare(previous_background_image_opacity_, qreal(0.0))) {
          background_painter.setOpacity(1.0 -
                                        previous_background_image_opacity_);
        }
        background_painter.drawPixmap(
            (width() - cached_scaled_background_image_.width()) / 2,
            (height() - cached_scaled_background_image_.height()) / 2,
            cached_scaled_background_image_);
      }
      // Draw the previous background image if we're fading
      if (!previous_background_image_.isNull()) {
        background_painter.setOpacity(previous_background_image_opacity_);
        background_painter.drawPixmap(
            (width() - previous_background_image_.width()) / 2,
            (height() - previous_background_image_.height()) / 2,
            previous_background_image_);
      }
    }
  }

  QPainter p(viewport());

  if (drop_indicator_row_ != -1) {
    if (cached_tree_.isNull()) {
      cached_tree_ = QPixmap(size());
      cached_tree_.fill(Qt::transparent);

      QPainter cache_painter(&cached_tree_);
      drawTree(&cache_painter, event->region());
    }

    p.drawPixmap(0, 0, cached_tree_);
  } else {
    drawTree(&p, event->region());
    return;
  }

  const int first_column = header_->logicalIndex(0);

  // Find the y position of the drop indicator
  QModelIndex drop_index = model()->index(drop_indicator_row_, first_column);
  int drop_pos = -1;
  switch (dropIndicatorPosition()) {
    case QAbstractItemView::OnItem:
      return;  // Don't draw anything

    case QAbstractItemView::AboveItem:
      drop_pos = visualRect(drop_index).top();
      break;

    case QAbstractItemView::BelowItem:
      drop_pos = visualRect(drop_index).bottom() + 1;
      break;

    case QAbstractItemView::OnViewport:
      if (model()->rowCount() == 0)
        drop_pos = 1;
      else
        drop_pos = 1 + visualRect(model()->index(model()->rowCount() - 1,
                                                 first_column)).bottom();
      break;
  }

  // Draw a nice gradient first
  QColor line_color(QApplication::palette().color(QPalette::Highlight));
  QColor shadow_color(line_color.lighter(140));
  QColor shadow_fadeout_color(shadow_color);
  shadow_color.setAlpha(255);
  shadow_fadeout_color.setAlpha(0);

  QLinearGradient gradient(QPoint(0, drop_pos - kDropIndicatorGradientWidth),
                           QPoint(0, drop_pos + kDropIndicatorGradientWidth));
  gradient.setColorAt(0.0, shadow_fadeout_color);
  gradient.setColorAt(0.5, shadow_color);
  gradient.setColorAt(1.0, shadow_fadeout_color);
  QPen gradient_pen(QBrush(gradient), kDropIndicatorGradientWidth * 2);
  p.setPen(gradient_pen);
  p.drawLine(QPoint(0, drop_pos), QPoint(width(), drop_pos));

  // Now draw the line on top
  QPen line_pen(line_color, kDropIndicatorWidth);
  p.setPen(line_pen);
  p.drawLine(QPoint(0, drop_pos), QPoint(width(), drop_pos));
}