From f6ac03f609bf002a678c1520104b87fdf03d0897 Mon Sep 17 00:00:00 2001 From: Taylor Bockman Date: Wed, 7 Aug 2019 22:29:06 -0700 Subject: [PATCH] Alot of work towards drawing points --- clusterview/exceptions.py | 4 ++- clusterview/mode.py | 16 +++++++++-- clusterview/opengl_widget.py | 67 +++++++++++++++++++++++++++++++++++++++++++- main_window.py | 7 +++-- 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/clusterview/exceptions.py b/clusterview/exceptions.py index 13d3b3b..67fcbd9 100644 --- a/clusterview/exceptions.py +++ b/clusterview/exceptions.py @@ -28,8 +28,10 @@ def handle_exceptions(func): return wrapped +class InvalidStateError(Exception): + pass -class InvalidMode(Exception): +class InvalidModeError(Exception): """ An exception to specify an invalid mode has been provided. """ diff --git a/clusterview/mode.py b/clusterview/mode.py index b948a1a..b0ee528 100644 --- a/clusterview/mode.py +++ b/clusterview/mode.py @@ -1,5 +1,7 @@ from enum import Enum +from clusterview.opengl_widget import set_drawing_mode + class Mode(Enum): """ Class to make it easier to figure out what mode @@ -14,11 +16,18 @@ class Mode(Enum): def __handle_add_point(ctx, event): """ - TODO: These functions should all take a context to - the openGL widget that will perform the - function. + Event handler for the add point mode. + + 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. """ print("[ADD] GOT POINT: ({}, {})".format(event.x(), event.y())) + # Convert to our point representation and add to list widget + # Point representation is a class called Point with coordinates, + # and attributes (currently always None) + # + set_drawing_mode(Mode.ADD, event) def __handle_edit_point(ctx, event): # TODO: This function and delete definitely need to make sure they are @@ -34,6 +43,7 @@ def __handle_edit_point(ctx, event): # applicable. print("[EDIT] GOT POINT: ({}, {})".format(event.x(), event.y())) + def __handle_move_points(ctx, event): # TODO: Should move the associated points in the list to the new location. print("[MOVE] Pressed - NOTE NEED DRAG EVENT") diff --git a/clusterview/opengl_widget.py b/clusterview/opengl_widget.py index 781e983..f4f2943 100644 --- a/clusterview/opengl_widget.py +++ b/clusterview/opengl_widget.py @@ -12,7 +12,12 @@ that widget. from enum import Enum -from OpenGL.GL import glClearColor, glEnable, GL_LIGHT0, GL_LIGHTING +from OpenGL.GL import (glBegin, glClearColor, glColor4f, glEnable, + glEnd, GL_LIGHT0, GL_LIGHTING, GL_POINTS, + glVertex3f) + +from clusterview.exceptions import InvalidStateError +from clusterview.mode import InvalidMode, Mode class Color(Enum): BLUE = 0 @@ -22,6 +27,37 @@ COLOR_TO_RGBA = { Color.BLUE: (0, 128, 255, 255) } +__current_mode = None +__current_event = None + +def set_drawing_mode(mode, event=None): + """ + State management function. It is useful to look at the + different drawing modes as modes in a state machine. + + Calling this function when a mode changes allows the + OpenGL functions to take the correct drawing action + on the OpenGL Widget. + + @param mode The current mode. + @param event The current event (Mostly used for passing coordinates). + """ + if not isinstance(mode, Mode): + raise ValueError("Mode in set_drawing_mode must be of type Mode") + + __current_mode = mode + + if event is not None: + __current_event = event + + +def get_current_mode(): + """ + Returns the current mode according to the OpenGL Widget. + """ + return __current_mode + + def initialize_gl(): """ Initializes the OpenGL context on the Window. @@ -35,6 +71,28 @@ def initialize_gl(): glClearColor(255, 255, 255, 0) +def paint_gl(): + """ + Stock PaintGL function from OpenGL that switches + on the current mode to determine what action to + perform on the current event. + """ + + if (__current_mode in [Mode.ADD, Mode.EDIT, Mode.MOVE, Mode.DELETE] and + __current_event is None): + raise InvalidStateError("Event must exist for ADD, EDIT, MOVE, " + + "and DELETE") + + if __current_mode is Mode.ADD: + raise NotImplementedError("Drawing for ADD not implemented.") + elif __current_mode is Mode.EDIT: + raise NotImplementedError("Drawing for EDIT not implemented.") + elif __current_mode is Mode.MOVE: + raise NotImplementedError("Drawing for MOVE not implemented.") + elif __current_mode is Mode.DELETE: + raise NotImplementedError("Drawing for DELETE not implemented.") + + def draw_point(x, y, color): """ Simple point drawing function. @@ -50,3 +108,10 @@ def draw_point(x, y, color): if not isinstance(color, Color): raise ValueError("Color must exist in the Color enumeration") + + ct = COLOR_TO_RGBA[color] + + glBegin(GL_POINTS) + glColor4f(ct[0], ct[1], ct[2], ct[3]) + glVertex3f(x, y, 0.0) # Z is currently fixed to 0 + glEnd() diff --git a/main_window.py b/main_window.py index 86b2eb9..6710602 100644 --- a/main_window.py +++ b/main_window.py @@ -5,9 +5,9 @@ from PyQt5.QtCore import Qt from PyQt5.QtGui import QCursor from PyQt5 import QtWidgets, uic -from clusterview.exceptions import handle_exceptions, InvalidMode +from clusterview.exceptions import handle_exceptions, InvalidModeError from clusterview.mode import Mode, MODE_MAP -from clusterview.opengl_widget import initialize_gl +from clusterview.opengl_widget import initialize_gl, paint_gl from clusterview_ui import Ui_MainWindow class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): @@ -28,6 +28,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): # here and defined in clusterview.opengl_widget. #----------------------------------------------- self.opengl_widget.initializeGL = initialize_gl + self.opengl_widget.paintGL = paint_gl # ------------------------------------- # UI Handlers @@ -80,7 +81,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): Mode dispatcher for click actions on the OpenGL widget. """ if self.__mode is Mode.OFF: - raise InvalidMode(Mode.OFF) + raise InvalidModeError(Mode.OFF) # Map from Mode -> function # where the function is a handler for the