Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add PyDMDrawingPolygon #376

Merged
merged 2 commits into from
Jul 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion docs/source/widgets/drawing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ PyDMDrawing Widgets

.. autoclass:: pydm.widgets.drawing.PyDMDrawingChord
:members:


.. autoclass:: pydm.widgets.drawing.PyDMDrawingPolygon
:members:
97 changes: 83 additions & 14 deletions examples/drawing/drawing_demo.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>646</width>
<height>510</height>
<width>651</width>
<height>662</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -449,51 +449,120 @@
<string>PyDMDrawingChord</string>
</property>
</widget>
<widget class="QLabel" name="label_10">
<property name="geometry">
<rect>
<x>20</x>
<y>510</y>
<width>151</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>PyDMDrawingPolygon</string>
</property>
</widget>
<widget class="PyDMDrawingPolygon" name="PyDMDrawingPolygon">
<property name="geometry">
<rect>
<x>40</x>
<y>540</y>
<width>100</width>
<height>100</height>
</rect>
</property>
<property name="toolTip">
<string/>
</property>
<property name="whatsThis">
<string>
A widget with a polygon drawn in it.
This class inherits from PyDMDrawing.

Parameters
----------
parent : QWidget
The parent widget for the Label
init_channel : str, optional
The channel to be used by the widget.
</string>
</property>
<property name="brush" stdset="0">
<brush brushstyle="Dense3Pattern">
<color alpha="255">
<red>28</red>
<green>153</green>
<blue>72</blue>
</color>
</brush>
</property>
<property name="penStyle" stdset="0">
<enum>Qt::SolidLine</enum>
</property>
<property name="penColor" stdset="0">
<color>
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="penWidth" stdset="0">
<double>4.000000000000000</double>
</property>
<property name="numberOfPoints" stdset="0">
<number>5</number>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>PyDMDrawingImage</class>
<class>PyDMDrawingArc</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingLine</class>
<extends>QWidget</extends>
<class>PyDMDrawingChord</class>
<extends>PyDMDrawingArc</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingRectangle</class>
<class>PyDMDrawingCircle</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingTriangle</class>
<class>PyDMDrawingEllipse</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingEllipse</class>
<class>PyDMDrawingImage</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingCircle</class>
<class>PyDMDrawingLine</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingArc</class>
<class>PyDMDrawingPie</class>
<extends>PyDMDrawingArc</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingPolygon</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingPie</class>
<extends>PyDMDrawingArc</extends>
<class>PyDMDrawingRectangle</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
<customwidget>
<class>PyDMDrawingChord</class>
<extends>PyDMDrawingArc</extends>
<class>PyDMDrawingTriangle</class>
<extends>QWidget</extends>
<header>pydm.widgets.drawing</header>
</customwidget>
</customwidgets>
Expand Down
4 changes: 3 additions & 1 deletion pydm/tests/test_plugins_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def test_import_drawing_plugins():
# Drawing plugins
from ..widgets.drawing import (PyDMDrawingLine, PyDMDrawingRectangle, PyDMDrawingTriangle,
PyDMDrawingEllipse, PyDMDrawingCircle, PyDMDrawingArc,
PyDMDrawingPie, PyDMDrawingChord, PyDMDrawingImage)
PyDMDrawingPie, PyDMDrawingChord, PyDMDrawingImage,
PyDMDrawingPolygon)

PyDMDrawingImagePlugin = qtplugin_factory(PyDMDrawingImage)
PyDMDrawingLinePlugin = qtplugin_factory(PyDMDrawingLine)
Expand All @@ -26,6 +27,7 @@ def test_import_drawing_plugins():
PyDMDrawingArcPlugin = qtplugin_factory(PyDMDrawingArc)
PyDMDrawingPiePlugin = qtplugin_factory(PyDMDrawingPie)
PyDMDrawingChordPlugin = qtplugin_factory(PyDMDrawingChord)
PyDMDrawingChordPlugin = qtplugin_factory(PyDMDrawingPolygon)

def test_import_embedded_display_plugin():
# Embedded Display plugin
Expand Down
52 changes: 51 additions & 1 deletion pydm/tests/widgets/test_drawing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
PyDMDrawingRectangle, PyDMDrawingTriangle,
PyDMDrawingEllipse,
PyDMDrawingCircle, PyDMDrawingArc,
PyDMDrawingPie, PyDMDrawingChord)
PyDMDrawingPie, PyDMDrawingChord,
PyDMDrawingPolygon)

from ...utilities import is_pydm_app

Expand Down Expand Up @@ -1112,6 +1113,55 @@ def test_pydmdrawingchord_draw_item(qtbot, monkeypatch, width, height,

pydm_drawingchord.draw_item()

# # ---------------------
# # PyDMDrawingPolygon
# # ---------------------
@pytest.mark.parametrize("x, y, width, height, num_points, expected_points", [
(0, 0, 100, 100, 3, [(50.0, 0),(-25, 43.3012),(-25, -43.3012)]),
(0, 0, 100, 100, 4, [(50.0, 0), (0, 50.0), (-50.0, 0), (0, -50.0)])
])
def test_pydmdrawingpolygon_calculate_drawing_points(qtbot, x, y, width,
height, num_points,
expected_points):
"""
Test the calculations of the point coordinates of a PyDMDrawingTriangle widget.

Expectations:
The calculations match with the expected values.

Parameters
----------
qtbot : fixture
Window for widget testing
x : int, float
The x-coordinate
y: int, float
The y-coordinate
width : int, float
The base measurement
height : int, float
The height measurement
num_points : int
The number of points in the polygon
expected_points : tuple
The collection of the x and y coordinate sets
"""
drawing = PyDMDrawingPolygon()
qtbot.addWidget(drawing)

drawing.numberOfPoints = num_points

assert drawing.numberOfPoints == num_points

calculated_points = drawing._calculate_drawing_points(x, y,
width,
height)

for idx, p in enumerate(calculated_points):
assert p.x() == pytest.approx(expected_points[idx][0], 0.1)
assert p.y() == pytest.approx(expected_points[idx][1], 0.1)

drawing.draw_item()

# --------------------
# NEGATIVE TEST CASES
Expand Down
63 changes: 61 additions & 2 deletions pydm/widgets/drawing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import logging

from ..PyQt.QtGui import (QApplication, QWidget, QColor, QPainter, QBrush, QPen,
QPolygon, QPixmap, QStyle, QStyleOption, QMovie)
from ..PyQt.QtCore import pyqtProperty, Qt, QPoint, QSize, pyqtSlot
QPolygon, QPolygonF, QPixmap, QStyle, QStyleOption,
QMovie)
from ..PyQt.QtCore import pyqtProperty, Qt, QPoint, QPointF, QSize, pyqtSlot
from ..PyQt.QtDesigner import QDesignerFormWindowInterface
from .base import PyDMWidget
from ..utilities import is_pydm_app
Expand Down Expand Up @@ -878,3 +879,61 @@ def draw_item(self):
x, y, w, h = self.get_bounds(maxsize=maxsize)
self._painter.drawChord(x, y, w, h, self._start_angle, self._span_angle)


class PyDMDrawingPolygon(PyDMDrawing):
"""
A widget with a polygon drawn in it.
This class inherits from PyDMDrawing.

Parameters
----------
parent : QWidget
The parent widget for the Label
init_channel : str, optional
The channel to be used by the widget.
"""
def __init__(self, parent=None, init_channel=None):
super(PyDMDrawingPolygon, self).__init__(parent, init_channel)
self._num_points = 3

@pyqtProperty(int)
def numberOfPoints(self):
"""
PyQT Property for the number of points

Returns
-------
int
Number of Points
"""
return self._num_points

@numberOfPoints.setter
def numberOfPoints(self, points):
if points >= 3 and points != self._num_points:
self._num_points = points
self.update()

def _calculate_drawing_points(self, x, y, w, h):
#(x + r*cos(theta), y + r*sin(theta))
r = min(w, h)/2.0
deg_step = 360.0/self._num_points

points = []
for i in range(self._num_points):
xp = r * math.cos(math.radians(deg_step * i))
yp = r * math.sin(math.radians(deg_step * i))
points.append(QPointF(xp, yp))

return points

def draw_item(self):
"""
Draws the Polygon after setting up the canvas with a call to
```PyDMDrawing.draw_item```.
"""
super(PyDMDrawingPolygon, self).draw_item()
maxsize = not self.is_square()
x, y, w, h = self.get_bounds(maxsize=not self.is_square())
poly = self._calculate_drawing_points(x, y, w, h)
self._painter.drawPolygon(QPolygonF(poly))
4 changes: 3 additions & 1 deletion pydm/widgets/qtplugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from .checkbox import PyDMCheckbox
from .drawing import (PyDMDrawingLine, PyDMDrawingRectangle, PyDMDrawingTriangle,
PyDMDrawingEllipse, PyDMDrawingCircle, PyDMDrawingArc,
PyDMDrawingPie, PyDMDrawingChord, PyDMDrawingImage)
PyDMDrawingPie, PyDMDrawingChord, PyDMDrawingImage,
PyDMDrawingPolygon)

from .embedded_display import PyDMEmbeddedDisplay
from .enum_combo_box import PyDMEnumComboBox
Expand Down Expand Up @@ -57,6 +58,7 @@
PyDMDrawingImagePlugin = qtplugin_factory(PyDMDrawingImage, group=WidgetCategory.DRAWING)
PyDMDrawingLinePlugin = qtplugin_factory(PyDMDrawingLine, group=WidgetCategory.DRAWING)
PyDMDrawingPiePlugin = qtplugin_factory(PyDMDrawingPie, group=WidgetCategory.DRAWING)
PyDMDrawingPolygonPlugin = qtplugin_factory(PyDMDrawingPolygon, group=WidgetCategory.DRAWING)
PyDMDrawingRectanglePlugin = qtplugin_factory(PyDMDrawingRectangle, group=WidgetCategory.DRAWING)
PyDMDrawingTrianglePlugin = qtplugin_factory(PyDMDrawingTriangle, group=WidgetCategory.DRAWING)

Expand Down