509 m_virtHeight = (m_height * m_virtWidth) / m_width; |
509 m_virtHeight = (m_height * m_virtWidth) / m_width; |
510 |
510 |
511 initGLData(); |
511 initGLData(); |
512 drawGLScene(); |
512 drawGLScene(); |
513 |
513 |
|
514 QPen textpen = getTextPen(); |
514 QPainter paint (this); |
515 QPainter paint (this); |
515 QFontMetrics metrics = QFontMetrics (QFont()); |
516 QFontMetrics metrics = QFontMetrics (QFont()); |
516 paint.setRenderHint (QPainter::HighQualityAntialiasing); |
517 paint.setRenderHint (QPainter::HighQualityAntialiasing); |
517 |
518 |
518 // If we wish to only draw the brick, stop here |
519 // If we wish to only draw the brick, stop here |
538 QFontMetrics metrics = QFontMetrics (font()); |
539 QFontMetrics metrics = QFontMetrics (font()); |
539 QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text); |
540 QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text); |
540 |
541 |
541 paint.setPen (getTextPen()); |
542 paint.setPen (getTextPen()); |
542 paint.drawText (m_width - textSize.width(), m_height - 16, textSize.width(), |
543 paint.drawText (m_width - textSize.width(), m_height - 16, textSize.width(), |
543 textSize.height(), Qt::AlignCenter, text); |
544 textSize.height(), Qt::AlignCenter, text); |
|
545 |
|
546 QPen linepen = m_thinBorderPen; |
|
547 linepen.setWidth (2); |
|
548 linepen.setColor (luma (m_bgcolor) < 40 ? Qt::white : Qt::black); |
544 |
549 |
545 // If we're drawing, draw the vertices onto the screen. |
550 // If we're drawing, draw the vertices onto the screen. |
546 if (editMode() == Draw) |
551 if (editMode() == Draw) |
547 { int numverts = 4; |
552 { int numverts = 4; |
548 |
553 |
584 polyverts[0] = m_hoverpos; |
589 polyverts[0] = m_hoverpos; |
585 } |
590 } |
586 } |
591 } |
587 |
592 |
588 // Draw the polygon-to-be |
593 // Draw the polygon-to-be |
589 QPen pen = m_thinBorderPen; |
594 paint.setPen (linepen); |
590 pen.setWidth (2); |
|
591 pen.setColor (luma (m_bgcolor) < 40 ? Qt::white : Qt::black); |
|
592 paint.setPen (pen); |
|
593 paint.setBrush (QColor (64, 192, 0, 128)); |
595 paint.setBrush (QColor (64, 192, 0, 128)); |
594 paint.drawPolygon (poly, numverts); |
596 paint.drawPolygon (poly, numverts); |
595 |
597 |
596 // Draw vertex blips |
598 // Draw vertex blips |
597 for (int i = 0; i < numverts; ++i) |
599 for (int i = 0; i < numverts; ++i) |
601 // Draw their coordinates |
603 // Draw their coordinates |
602 paint.drawText (blip.x(), blip.y() - 8, polyverts[i].stringRep (true)); |
604 paint.drawText (blip.x(), blip.y() - 8, polyverts[i].stringRep (true)); |
603 } |
605 } |
604 } |
606 } |
605 } |
607 } |
606 |
|
607 elif (editMode() == CircleMode) |
608 elif (editMode() == CircleMode) |
608 { // If we have not specified the center point of the circle yet, preview it on the screen. |
609 { // If we have not specified the center point of the circle yet, preview it on the screen. |
609 if (m_drawedVerts.size() == 0) |
610 if (m_drawedVerts.size() == 0) |
610 drawBlip (paint, coordconv3_2 (m_hoverpos)); |
611 drawBlip (paint, coordconv3_2 (m_hoverpos)); |
611 else |
612 else |
612 { QVector<vertex> verts; |
613 { QVector<vertex> verts; |
613 const double dist = circleDrawDist(); |
614 const double dist = circleDrawDist(); |
614 const int segs = lores; |
615 const int segs = lores; |
615 const double angleUnit = (2 * pi) / segs; |
616 const double angleUnit = (2 * pi) / segs; |
616 Axis relX, relY; |
617 Axis relX, relY; |
|
618 QVector<QPoint> points; |
|
619 |
617 getRelativeAxes (relX, relY); |
620 getRelativeAxes (relX, relY); |
618 |
621 |
619 for (int i = 0; i < segs; ++i) |
622 for (int i = 0; i < segs; ++i) |
620 { vertex v = g_origin; |
623 { vertex v = g_origin; |
621 v[relX] = m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist); |
624 v[relX] = m_drawedVerts[0][relX] + (cos (i * angleUnit) * dist); |
622 v[relY] = m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist); |
625 v[relY] = m_drawedVerts[0][relY] + (sin (i * angleUnit) * dist); |
623 verts << v; |
626 verts << v; |
624 } |
627 } |
625 |
628 |
626 QVector<QPoint> points; |
629 for (const vertex& v : verts) |
627 |
|
628 for (const vertex & v : verts) |
|
629 { QPoint point = coordconv3_2 (v); |
630 { QPoint point = coordconv3_2 (v); |
630 drawBlip (paint, point); |
631 drawBlip (paint, point); |
631 points << point; |
632 points << point; |
632 } |
633 } |
633 |
634 |
634 QPen pen = m_thinBorderPen; |
635 paint.setPen (linepen); |
635 pen.setWidth (2); |
|
636 pen.setColor (luma (m_bgcolor) < 40 ? Qt::white : Qt::black); |
|
637 paint.setPen (pen); |
|
638 paint.setBrush (Qt::NoBrush); |
636 paint.setBrush (Qt::NoBrush); |
639 paint.drawPolygon (QPolygon (points)); |
637 paint.drawPolygon (QPolygon (points)); |
|
638 |
|
639 { // Draw the current radius in the middle of the circle. |
|
640 QPoint origin = coordconv3_2 (m_drawedVerts[0]); |
|
641 str label = str::number (dist); |
|
642 paint.setPen (textpen); |
|
643 paint.drawText (origin.x() - (metrics.width (label) / 2), origin.y(), label); |
|
644 } |
640 } |
645 } |
641 } |
646 } |
642 } |
647 } |
643 |
648 |
644 // Camera icons |
649 // Camera icons |
647 paint.setPen (m_thinBorderPen); |
652 paint.setPen (m_thinBorderPen); |
648 paint.setBrush (QBrush (QColor (0, 128, 160, 128))); |
653 paint.setBrush (QBrush (QColor (0, 128, 160, 128))); |
649 paint.drawRect (m_cameraIcons[camera()].selRect); |
654 paint.drawRect (m_cameraIcons[camera()].selRect); |
650 |
655 |
651 // Draw the actual icons |
656 // Draw the actual icons |
652 for (CameraIcon & info : m_cameraIcons) |
657 for (CameraIcon& info : m_cameraIcons) |
653 { // Don't draw the free camera icon when in draw mode |
658 { // Don't draw the free camera icon when in draw mode |
654 if (&info == &m_cameraIcons[GL::Free] && editMode() != Select) |
659 if (&info == &m_cameraIcons[GL::Free] && editMode() != Select) |
655 continue; |
660 continue; |
656 |
661 |
657 paint.drawPixmap (info.destRect, *info.img, info.srcRect); |
662 paint.drawPixmap (info.destRect, *info.img, info.srcRect); |
658 } |
663 } |
659 |
664 |
660 str fmtstr = tr ("%1 Camera"); |
665 str fmtstr = tr ("%1 Camera"); |
661 |
666 |
662 // Draw a label for the current camera in the bottom left corner |
667 // Draw a label for the current camera in the bottom left corner |
663 { const ushort margin = 4; |
668 { const int margin = 4; |
664 |
669 |
665 str label; |
670 str label; |
666 label = fmt (fmtstr, tr (g_CameraNames[camera()])); |
671 label = fmt (fmtstr, tr (g_CameraNames[camera()])); |
667 paint.setPen (getTextPen()); |
672 paint.setPen (textpen); |
668 paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label); |
673 paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label); |
669 } |
674 } |
670 |
675 |
671 // Tool tips |
676 // Tool tips |
672 if (m_drawToolTip) |
677 if (m_drawToolTip) |
683 if (msglog()) |
688 if (msglog()) |
684 { int y = 0; |
689 { int y = 0; |
685 const int margin = 2; |
690 const int margin = 2; |
686 QColor penColor = getTextPen(); |
691 QColor penColor = getTextPen(); |
687 |
692 |
688 for (const MessageManager::Line & line : msglog()->getLines()) |
693 for (const MessageManager::Line& line : msglog()->getLines()) |
689 { penColor.setAlphaF (line.alpha); |
694 { penColor.setAlphaF (line.alpha); |
690 paint.setPen (penColor); |
695 paint.setPen (penColor); |
691 paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text); |
696 paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text); |
692 y += metrics.height(); |
697 y += metrics.height(); |
693 } |
698 } |
694 } |
699 } |
695 |
700 |
696 // If we're range-picking, draw a rectangle encompassing the selection area. |
701 // If we're range-picking, draw a rectangle encompassing the selection area. |
697 if (m_rangepick && !m_picking && m_totalmove >= 10) |
702 if (m_rangepick && !m_picking && m_totalmove >= 10) |
698 { const short x0 = m_rangeStart.x(), |
703 { int x0 = m_rangeStart.x(), |
699 y0 = m_rangeStart.y(), |
704 y0 = m_rangeStart.y(), |
700 x1 = m_pos.x(), |
705 x1 = m_pos.x(), |
701 y1 = m_pos.y(); |
706 y1 = m_pos.y(); |
702 |
707 |
703 QRect rect (x0, y0, x1 - x0, y1 - y0); |
708 QRect rect (x0, y0, x1 - x0, y1 - y0); |
704 QColor fillColor = (m_addpick ? "#40FF00" : "#00CCFF"); |
709 QColor fillColor = (m_addpick ? "#40FF00" : "#00CCFF"); |
705 fillColor.setAlphaF (0.2f); |
710 fillColor.setAlphaF (0.2f); |
706 |
711 |
912 updateRectVerts(); |
917 updateRectVerts(); |
913 } |
918 } |
914 } |
919 } |
915 |
920 |
916 addDrawnVertex (m_hoverpos); |
921 addDrawnVertex (m_hoverpos); |
917 break; |
922 } break; |
918 |
923 |
919 case CircleMode: |
924 case CircleMode: |
920 |
925 { if (m_drawedVerts.size() == 2) |
921 if (m_drawedVerts.size() == 2) |
|
922 { endDraw (true); |
926 { endDraw (true); |
923 return; |
927 return; |
924 } |
928 } |
925 |
929 |
926 addDrawnVertex (m_hoverpos); |
930 addDrawnVertex (m_hoverpos); |
927 break; |
931 } break; |
928 |
932 |
929 case Select: |
933 case Select: |
930 |
934 { if (!drawOnly()) |
931 if (!drawOnly()) |
|
932 { if (m_totalmove < 10) |
935 { if (m_totalmove < 10) |
933 m_rangepick = false; |
936 m_rangepick = false; |
934 |
937 |
935 if (!m_rangepick) |
938 if (!m_rangepick) |
936 m_addpick = (m_keymods & Qt::ControlModifier); |
939 m_addpick = (m_keymods & Qt::ControlModifier); |
937 |
940 |
938 if (m_totalmove < 10 || m_rangepick) |
941 if (m_totalmove < 10 || m_rangepick) |
939 pick (ev->x(), ev->y()); |
942 pick (ev->x(), ev->y()); |
940 } |
943 } |
941 |
944 } break; |
942 break; |
|
943 } |
945 } |
944 |
946 |
945 m_rangepick = false; |
947 m_rangepick = false; |
946 } |
948 } |
947 |
949 |
951 vertex closest; |
953 vertex closest; |
952 bool valid = false; |
954 bool valid = false; |
953 |
955 |
954 QPoint curspos = coordconv3_2 (m_hoverpos); |
956 QPoint curspos = coordconv3_2 (m_hoverpos); |
955 |
957 |
956 for (const vertex & pos3d: m_knownVerts) |
958 for (const vertex& pos3d: m_knownVerts) |
957 { QPoint pos2d = coordconv3_2 (pos3d); |
959 { QPoint pos2d = coordconv3_2 (pos3d); |
958 |
960 |
959 // Measure squared distance |
961 // Measure squared distance |
960 const double dx = abs (pos2d.x() - curspos.x()), |
962 const double dx = abs (pos2d.x() - curspos.x()), |
961 dy = abs (pos2d.y() - curspos.y()), |
963 dy = abs (pos2d.y() - curspos.y()), |
1241 SET_ACCESSOR (EditMode, GLRenderer::setEditMode) |
1243 SET_ACCESSOR (EditMode, GLRenderer::setEditMode) |
1242 { m_editMode = val; |
1244 { m_editMode = val; |
1243 |
1245 |
1244 switch (editMode()) |
1246 switch (editMode()) |
1245 { case Select: |
1247 { case Select: |
1246 unsetCursor(); |
1248 { unsetCursor(); |
1247 setContextMenuPolicy (Qt::DefaultContextMenu); |
1249 setContextMenuPolicy (Qt::DefaultContextMenu); |
1248 break; |
1250 } break; |
1249 |
1251 |
1250 case Draw: |
1252 case Draw: |
1251 case CircleMode: |
1253 case CircleMode: |
1252 |
1254 { // Cannot draw into the free camera - use top instead. |
1253 // Cannot draw into the free camera - use top instead. |
|
1254 if (m_camera == Free) |
1255 if (m_camera == Free) |
1255 setCamera (Top); |
1256 setCamera (Top); |
1256 |
1257 |
1257 // Disable the context menu - we need the right mouse button |
1258 // Disable the context menu - we need the right mouse button |
1258 // for removing vertices. |
1259 // for removing vertices. |
1265 // FIXME: make the selection clearing stuff in ::pick a method and use it |
1266 // FIXME: make the selection clearing stuff in ::pick a method and use it |
1266 // here! This code doesn't update the GL lists. |
1267 // here! This code doesn't update the GL lists. |
1267 g_win->sel().clear(); |
1268 g_win->sel().clear(); |
1268 g_win->updateSelection(); |
1269 g_win->updateSelection(); |
1269 m_drawedVerts.clear(); |
1270 m_drawedVerts.clear(); |
1270 break; |
1271 } break; |
1271 } |
1272 } |
1272 |
1273 |
1273 g_win->updateEditModeActions(); |
1274 g_win->updateEditModeActions(); |
1274 update(); |
1275 update(); |
1275 } |
1276 } |
1351 matrix transform = g_circleDrawTransforms[camera() % 3]; |
1352 matrix transform = g_circleDrawTransforms[camera() % 3]; |
1352 |
1353 |
1353 for (int i = 0; i < 9; ++i) |
1354 for (int i = 0; i < 9; ++i) |
1354 { if (transform[i] == 2) |
1355 { if (transform[i] == 2) |
1355 transform[i] = dist; |
1356 transform[i] = dist; |
1356 |
|
1357 elif (transform[i] == 1 && camera() >= 3) |
1357 elif (transform[i] == 1 && camera() >= 3) |
1358 transform[i] = -1; |
1358 transform[i] = -1; |
1359 } |
1359 } |
1360 |
1360 |
1361 LDSubfile* ref = new LDSubfile; |
1361 LDSubfile* ref = new LDSubfile; |
1362 ref->setFileInfo (findLoadedFile ("4-4edge.dat")); |
1362 ref->setFileInfo (findLoadedFile ("4-4edge.dat")); |
1363 ref->setTransform (transform); |
1363 ref->setTransform (transform); |