Download src/Mod/TechDraw/Gui/Widgets/CompassDialWidget.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 9.59 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/TechDraw/Gui/Widgets/CompassDialWidget.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/TechDraw/Gui/Widgets/CompassDialWidget.cpp
-
curl -L -o CompassDialWidget.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/TechDraw/Gui/Widgets/CompassDialWidget.cpp
9.59 kB
| /*************************************************************************** | |
| * Copyright (c) 2022 WandererFan <wandererfan@gmail.com> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ***************************************************************************/ | |
| //largely based on a python widget from: | |
| //https://github.com/tcalmant/demo-ipopo-qt/blob/master/pc/details/compass.py | |
| using namespace TechDrawGui; | |
| using CardinalMap = std::map<int, std::string>; | |
| CompassDialWidget::CompassDialWidget(QWidget* parent) : QWidget(parent), | |
| m_markInterval(15), | |
| m_defaultSize(75), | |
| m_defaultMargin(10), | |
| m_designRadius(64) | |
| { | |
| setObjectName(QStringLiteral("Compass")); | |
| m_rect = QRect(0, 0, m_defaultSize, m_defaultSize); | |
| m_angle = 0.0; | |
| m_margin = m_defaultMargin; | |
| m_designDiameter = 2 * m_designRadius; | |
| QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); | |
| sizePolicy.setHorizontalStretch(1); | |
| sizePolicy.setVerticalStretch(1); | |
| setSizePolicy(sizePolicy); | |
| repaint(); | |
| } | |
| QSize CompassDialWidget::sizeHint() const | |
| { | |
| return m_rect.size(); | |
| } | |
| QSize CompassDialWidget::minimumSizeHint() const | |
| { | |
| return QRect(0, 0, m_defaultSize, m_defaultSize).size(); | |
| } | |
| void CompassDialWidget::paintEvent(QPaintEvent* event) | |
| { | |
| Q_UNUSED(event); | |
| QPainter painter(this); | |
| drawWidget(painter); | |
| QWidget::paintEvent(event); | |
| } | |
| void CompassDialWidget::drawWidget(QPainter& painter) | |
| { | |
| painter.setRenderHint(QPainter::Antialiasing, true); | |
| // Draw the background | |
| drawBackground(painter); | |
| //Draw the cardinal points | |
| drawMarkings(painter); | |
| //Draw the needle | |
| drawNeedle(painter); | |
| } | |
| void CompassDialWidget::drawBackground(QPainter& painter) | |
| { | |
| painter.save(); | |
| //Move to the center of the compass | |
| painter.translate(width() / 2, height() / 2); | |
| double scale = std::min((float) width() / (float) (m_designDiameter + 2.0 * m_margin), | |
| (float) height() / (float) (m_designDiameter + 2.0 * m_margin)); | |
| painter.scale(scale, scale); | |
| painter.setPen(QPen(Qt::NoPen)); | |
| // Clear the background | |
| int circleWidth = 2.0 * (m_designRadius + m_margin); | |
| int circleHeight = 2.0 * (m_designRadius + m_margin); | |
| QRect circleRect(-circleWidth / 2, -circleHeight / 2, circleWidth, circleHeight); | |
| painter.drawEllipse(circleRect); | |
| // QRect backRect(-m_rect.width() / 2, -m_rect.height() / 2, m_rect.width(), m_rect.height()); | |
| QPainterPath backPath; | |
| backPath.addEllipse(circleRect); | |
| painter.fillPath(backPath, palette().brush((QPalette::Window))); | |
| // painter.fillRect(backRect, palette().brush((QPalette::Window))); | |
| painter.restore(); | |
| } | |
| //Draws the cardinal points on painter. This widget was designed such that | |
| //the dial gradations extend to 50 units from center and the compass point text | |
| //begins at 52 units from the center. With the font size set to 12 pixels, this | |
| //gives a design area of a circle with a radius of approximately 64 units. All of | |
| //the constants reflect this design size. | |
| void CompassDialWidget::drawMarkings(QPainter& painter) | |
| { | |
| CardinalMap CompassPointText( { {0, "Y"}, {45, "XY"}, {90, "X"}, {135, "X-Y"}, {180, "-Y"}, | |
| {225, "-X-Y"}, {270, "-X"}, {315, "-XY"} } ); | |
| painter.save(); | |
| int markInterval(15); | |
| //Move to the center of the compass | |
| painter.translate(width() / 2, height() / 2); | |
| double scale = std::min((float) width() / (float) (m_designDiameter + 2.0 * m_margin), | |
| (float) height() / (float) (m_designDiameter + 2.0 * m_margin)); | |
| painter.scale(scale, scale); | |
| // Setup the fonts and the painter | |
| QFont widgetFont = font(); | |
| widgetFont.setPixelSize(12); | |
| QFontMetrics metrics(widgetFont); | |
| //outer circle | |
| int circleWidth = 2.0 * (m_designRadius + m_margin); | |
| int circleHeight = 2.0 * (m_designRadius + m_margin); | |
| QRect circleRect(-circleWidth / 2, -circleHeight / 2, circleWidth, circleHeight); | |
| painter.drawEllipse(circleRect); | |
| painter.setFont(widgetFont); | |
| painter.setPen(QPen(palette().color(QPalette::WindowText))); | |
| int iDegree = 0; | |
| while ( iDegree < 360 ) { | |
| if (iDegree % 45 == 0) { | |
| //Named direction (every 45°) | |
| painter.drawLine(0, -40, 0, -50); //this has to depend on m_rect or size? | |
| QString qPointText = QString::fromStdString(CompassPointText.at(iDegree)); | |
| painter.drawText(-metrics.boundingRect(qPointText).width() / 2.0, -52, qPointText); | |
| // what is -52? line end point y = -50 + 2 for margin? | |
| } else { | |
| //Small line | |
| painter.drawLine(0, -45, 0, -50); | |
| } | |
| //Next line (+15°) | |
| painter.rotate(markInterval); | |
| iDegree += markInterval; | |
| } | |
| painter.restore(); | |
| } | |
| //Draws a needle on painter | |
| void CompassDialWidget::drawNeedle(QPainter& painter) | |
| { | |
| painter.save(); | |
| //Move to the center of the compass | |
| painter.translate(width() / 2, height() / 2); | |
| //Rotate to the correct angle | |
| painter.rotate(m_angle); | |
| double scale = std::min((float) width() / (float) (m_designDiameter + 2.0 * m_margin), | |
| (float) height() / (float) (m_designDiameter + 2.0 * m_margin)); | |
| painter.scale(scale, scale); | |
| //Setup the painter | |
| QPen needlePen(palette().color(QPalette::WindowText)); | |
| needlePen.setWidth(2); | |
| needlePen.setStyle(Qt::DashDotLine); | |
| painter.setPen(needlePen); | |
| painter.setBrush(palette().color(QPalette::WindowText)); | |
| //Draw the section line | |
| int sectionLineExtent(25); | |
| painter.drawLine(0, sectionLineExtent, 0, -sectionLineExtent); | |
| needlePen.setStyle(Qt::SolidLine); | |
| painter.setPen(needlePen); | |
| int viewDirectionExtent(15); | |
| painter.drawLine(-viewDirectionExtent, sectionLineExtent, 0, sectionLineExtent); | |
| painter.drawLine(-viewDirectionExtent, -sectionLineExtent, 0, -sectionLineExtent); | |
| //Draw the arrowheads of the needle section line | |
| needlePen.setWidth(1); | |
| needlePen.setStyle(Qt::SolidLine); | |
| painter.setPen(needlePen); | |
| int arrowLength(5); | |
| int arrowWidth(3); //actual 1/2 width | |
| painter.drawPolygon( | |
| QPolygon( { QPoint(0, sectionLineExtent), | |
| QPoint(-arrowLength, sectionLineExtent + arrowWidth), | |
| QPoint(-arrowLength, sectionLineExtent - arrowWidth), | |
| QPoint(0, sectionLineExtent) } ) ); | |
| painter.drawPolygon( | |
| QPolygon( { QPoint(0, -sectionLineExtent), | |
| QPoint(-arrowLength, -(sectionLineExtent + arrowWidth)), | |
| QPoint(-arrowLength, -(sectionLineExtent - arrowWidth)), | |
| QPoint(0, -sectionLineExtent) } ) ); | |
| //draw the actual needle | |
| needlePen.setStyle(Qt::SolidLine); | |
| painter.setPen(needlePen); | |
| painter.setBrush(palette().color(QPalette::BrightText)); | |
| int needleExtent(40); | |
| painter.drawPolygon( | |
| QPolygon( { QPoint(needleExtent, 0), | |
| QPoint(0, 5), | |
| QPoint(-15, 2), | |
| QPoint(-15, -2), | |
| QPoint(0, -5), | |
| QPoint(needleExtent, 0) } ) ); | |
| //draw needle pivot | |
| painter.setBrush(palette().color(QPalette::WindowText)); | |
| int pivotSize(4); | |
| QRect pivotRect(-pivotSize / 2, -pivotSize / 2, pivotSize, pivotSize); | |
| painter.drawEllipse(pivotRect); | |
| //draw needle point | |
| painter.setBrush(QBrush(Qt::red)); | |
| int pointLength(5); | |
| int pointWidth(3); | |
| painter.drawPolygon( | |
| QPolygon( { QPoint(needleExtent, 0), | |
| QPoint(needleExtent - pointLength, pointWidth), | |
| QPoint(needleExtent - pointLength, -pointWidth), | |
| QPoint(needleExtent, 0) } ) ); | |
| painter.restore(); | |
| } | |
| //convert a conventional angle to a Qt angle and set the dial accordingly | |
| void CompassDialWidget::setAngle(double newAngle) | |
| { | |
| m_angle = fmod(360.0 - newAngle, 360.0); | |
| repaint(); | |
| } | |
| void CompassDialWidget::setSize(int newSize) | |
| { | |
| m_rect = QRect(0, 0, newSize, newSize); | |
| repaint(); | |
| } | |