From ebb5bc9a8a51a0e6bf30cebd96bfcba2ccf4548e Mon Sep 17 00:00:00 2001 From: Taylor Bockman Date: Sat, 10 Aug 2019 21:18:48 -0700 Subject: [PATCH] Point display - edit, delete, move, etc tomorrow --- clusterview/mode_handlers.py | 33 ++++++++++++++++++++++++++++----- clusterview/opengl_widget.py | 43 +++++++++++++++++++++++++++++++++---------- main_window.py | 6 ++++-- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/clusterview/mode_handlers.py b/clusterview/mode_handlers.py index f6c5ab2..8c327b9 100644 --- a/clusterview/mode_handlers.py +++ b/clusterview/mode_handlers.py @@ -1,5 +1,11 @@ from .mode import Mode -from .opengl_widget import set_drawing_event +from .opengl_widget import set_current_points, set_drawing_event +from .points import PointSet + +# There are a lot of module-global variables being used because of the +# nature of state management in OpenGL. +__point_set = PointSet() + def __handle_add_point(ctx, event): """ @@ -8,12 +14,29 @@ def __handle_add_point(ctx, event): Sets the drawing mode for the OpenGL Widget using `set_drawing_mode`, converts a point to our point representation, and adds it to the list. + + @param ctx A context handle to the main window. + @param event The click event. """ + global __point_set + + # No attribute at the moment. + __point_set.add_point(event.x(), event.y()) + set_drawing_event(event) - ctx.update() - # Convert to our point representation and add to list widget - # Also force widget to update - also everywhere below any time you - # modify the point list you need to force update the point list widget. + set_current_points(__point_set) + + # In order to make some guarantees and avoid duplicate + # data we will clear the point list widget and re-populate + # it using the current __point_set. + ctx.point_list_widget.clear() + + for p in __point_set.points: + ctx.point_list_widget.addItem("({}, {})".format(p[0], p[1])) + + ctx.opengl_widget.update() + ctx.point_list_widget.update() + def __handle_edit_point(ctx, event): # TODO: This function and delete definitely need to make sure they are diff --git a/clusterview/opengl_widget.py b/clusterview/opengl_widget.py index 7310a62..3457860 100644 --- a/clusterview/opengl_widget.py +++ b/clusterview/opengl_widget.py @@ -18,6 +18,7 @@ from OpenGL.GL import (glBegin, glClearColor, glColor4f, glEnable, from .exceptions import InvalidModeError, InvalidStateError from .mode import Mode +from .points import PointSet class Color(Enum): BLUE = 0 @@ -45,6 +46,7 @@ __HEIGHT = None # function local. __current_mode = None __current_event = None +__current_points = None __current_context = None @@ -57,6 +59,25 @@ def set_drawing_context(ctx): __current_context = ctx +def set_current_points(points): + """ + Sets the point state variable that will be passed in to the paint_gl + function, and further to the point painter functions in order to + render the scene. + + Each time a point is added, removed, or edited this point set must be + updated. + + @param points The PointSet representing the current scene. + """ + global __current_points + + if not isinstance(points, PointSet): + raise ValueError("set_current_points must recieve a PointSet as its " + + "argument.") + + __current_points = points + def set_drawing_mode(mode): """ @@ -137,11 +158,13 @@ def paint_gl(): raise InvalidStateError("Event must exist for ADD, EDIT, MOVE, " + "and DELETE") + if (__current_mode in [Mode.ADD, Mode.EDIT, Mode.MOVE, Mode.DELETE] and + __current_points is None): + raise InvalidStateError("Points must exist for ADD, EDIT, MOVE, " + + "and DELETE") + if __current_mode is Mode.ADD: - # TODO: This needs to be modified to instead take the point list - # and redraw the entire list (which will have the new point - # added) each click. - draw_points(__current_event.x(), __current_event.y(), Color.BLUE) + draw_points(__current_points, Color.BLUE) elif __current_mode is Mode.EDIT: raise NotImplementedError("Drawing for EDIT not implemented.") elif __current_mode is Mode.MOVE: @@ -174,7 +197,7 @@ def __clamp_y(y): return y_w -def draw_points(x, y, color): +def draw_points(point_set, color): """ Simple point drawing function. @@ -182,8 +205,7 @@ def draw_points(x, y, color): function will draw the given point with the given color. - @param x The x-coordinate. - @param y The y-coordinate. + @param point_set The PointSet to draw. @param color The Color Enum. """ global __current_context @@ -202,9 +224,10 @@ def draw_points(x, y, color): glColor4f(ct[0], ct[1], ct[2], ct[3]) glBegin(GL_POINTS) - glVertex3f(__clamp_x(__current_event.x()), - __clamp_y(__current_event.y()), - 0.0) # Z is currently fixed to 0 + for point in point_set.points: + glVertex3f(__clamp_x(point[0]), + __clamp_y(point[1]), + 0.0) # Z is currently fixed to 0 glEnd() diff --git a/main_window.py b/main_window.py index 4f5b347..10f2f75 100644 --- a/main_window.py +++ b/main_window.py @@ -99,5 +99,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): # Map from Mode -> function # where the function is a handler for the - # OpenGL Widget. - MODE_HANDLER_MAP[self.__mode](self.opengl_widget, event) + # OpenGL event. The context passed to these functions allows + # them to modify on screen widgets such as the QOpenGLWidget and + # QListWidget. + MODE_HANDLER_MAP[self.__mode](self, event)