// Rotated Table Header Text Qt4 Experimentation -- 9-12-2008 // Phil's experimentation with custom drawing of rotated text in a Qt4 // QHeaderView. This is just a proof-of-concept. Two intermediate QPixmaps // are used, and that certainly isn't necessary -- they were introduced to // help idenify some difficulties I was having understanding the matrix // transforms. This code may have some one-off problems, but it's close. // The drawing of QPixmaps onto QPainters is rescaling to the target area -- // that should done without rescaling. Better yet, intermediate QPixmaps // should be eliminated. // Sample Diagnostic Output: // // RunAnalGridQHeaderView::paintSection [4]: '09-13-2008 24:00' // [72 --> 89; 0 --> 123] Cen: (61.5,8.5) // // Top: 0 --> -8 --> -61 --> 0 // Lft: 0 --> -61 --> 9 --> 17 // Bot: 17 --> 9 --> 62 --> 123 // Rgt: 123 --> 62 --> -8 --> 0 // // RunAnalGridQHeaderView::sizeHint: [30, 124] // //--- //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // virtual from QHeaderView void RunAnalGridQHeaderView::paintSection (QPainter* painter, const QRect& rect, int logicalIndex) const { static const char (*mname) ("RunAnalGridQHeaderView::paintSection"); //------------- painter->save(); //------------- const int rectLft (rect.left()); const int rectRgt (rect.right()); const int rectTop (rect.top()); const int rectBot (rect.bottom()); const QPalette& pal (palette()); QColor fgColor (pal.color (QPalette::WindowText)); QColor bgColor (pal.color (QPalette::Window)); const QFontMetrics fm (fontMetrics()); const QString colLabel = label (logicalIndex); // const int colLabelWidth = fm.width (colLabel) + 15; // const int colLabelHeight = fm.height() + 15; // // Note: given rectangle is for rotated geometry, but these dimensions // are for the un-rotated dimensions. const int colLabelWidth = std::max (1, (rectBot - rectTop)); // rotated const int colLabelHeight = std::max (1, (rectRgt - rectLft)); // rotated // ******************************************* // *** (1) Create Horizontal Text Pixmap *** // ******************************************* const QSize tmpHorzSize (colLabelWidth, colLabelHeight); const QRect tmpHorzRect (0, 0, colLabelWidth, colLabelHeight); const double tmpHorzCenterX (colLabelWidth * 0.5); const double tmpHorzCenterY (colLabelHeight * 0.5); QPixmap tmpHorzPmap (tmpHorzSize); QPainter pmapHorzPainter (&tmpHorzPmap); pmapHorzPainter.fillRect (tmpHorzRect, bgColor); pmapHorzPainter.setPen (fgColor); pmapHorzPainter.drawText (tmpHorzRect, Qt::AlignCenter, colLabel); // ***************************************** // *** (2) Create Vertical Text Pixmap *** // ***************************************** const QSize tmpVertSize (colLabelHeight, colLabelWidth); // swapped const QRect tmpVertRect (0, 0, colLabelHeight, colLabelWidth); // swapped const double tmpVertCenterX (colLabelHeight * 0.5); const double tmpVertCenterY (colLabelWidth * 0.5); QPixmap tmpVertPmap (tmpVertSize); QPainter pmapVertPainter (&tmpVertPmap); pmapVertPainter.fillRect (tmpVertRect, Qt::blue); pmapVertPainter.setPen (fgColor); std::cout << mname << " [" << logicalIndex << "]: " << "'" << qPrintable (colLabel) << "'" << " [" << rectLft << " --> " << rectRgt << "; " << rectTop << " --> " << rectBot << "]" << " Cen: (" << tmpHorzCenterX << "," << tmpHorzCenterY << ")" << std::endl; QMatrix xform1; xform1.translate (-tmpHorzCenterX, -tmpHorzCenterY); QMatrix xform2; xform2.rotate (90); QMatrix xform3; xform3.translate (tmpVertCenterX, tmpVertCenterY); QMatrix xformAll; const QPoint origTopLft (0, 0); const QPoint origBotRgt (colLabelWidth, colLabelHeight); // Transform Step 1 of 3 xformAll = xform1; const QPoint mapped1TopLft (xformAll.map (origTopLft)); const QPoint mapped1BotRgt (xformAll.map (origBotRgt)); // Transform Step 2 of 3 xformAll = xform1 * xform2; const QPoint mapped2TopLft (xformAll.map (origTopLft)); const QPoint mapped2BotRgt (xformAll.map (origBotRgt)); // Transform Step 3 of 3 xformAll = xform1 * xform2 * xform3; const QPoint mapped3TopLft (xformAll.map (origTopLft)); const QPoint mapped3BotRgt (xformAll.map (origBotRgt)); std::cout << " Top: " << origTopLft.y() << " --> " << mapped1TopLft.y() << " --> " << mapped2TopLft.y() << " --> " << mapped3TopLft.y() << std::endl; std::cout << " Lft: " << origTopLft.x() << " --> " << mapped1TopLft.x() << " --> " << mapped2TopLft.x() << " --> " << mapped3TopLft.x() << std::endl; std::cout << " Bot: " << origBotRgt.y() << " --> " << mapped1BotRgt.y() << " --> " << mapped2BotRgt.y() << " --> " << mapped3BotRgt.y() << std::endl; std::cout << " Rgt: " << origBotRgt.x() << " --> " << mapped1BotRgt.x() << " --> " << mapped2BotRgt.x() << " --> " << mapped3BotRgt.x() << std::endl; pmapVertPainter.setMatrix (xformAll); pmapVertPainter.drawPixmap (0, 0, tmpHorzPmap); // ********************************************************* // *** (3) Paint Vertical Text Pixmap into QHeaderView *** // ********************************************************* painter->fillRect (rect, bgColor); painter->drawPixmap (rect, tmpVertPmap); //----------------- painter->restore(); //----------------- // // call base class method // QHeaderView::paintSection (painter, rect, logicalIndex); } //--- (end) ---