From 461452a838c27968227af9ec9dac69a79c9e8bc2 Mon Sep 17 00:00:00 2001 From: Taylor Bockman Date: Thu, 15 Aug 2019 00:01:37 -0700 Subject: [PATCH] first pass at selecting points --- clusterview/mode_handlers.py | 10 ++--- clusterview/opengl_widget.py | 96 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/clusterview/mode_handlers.py b/clusterview/mode_handlers.py index f19aa58..f1445b8 100644 --- a/clusterview/mode_handlers.py +++ b/clusterview/mode_handlers.py @@ -1,7 +1,8 @@ from PyQt5.QtCore import QEvent, Qt from .mode import Mode -from .opengl_widget import (set_current_points, set_drawing_event, +from .opengl_widget import (get_bb_bottom_right, get_bb_top_left, + set_current_points, set_drawing_event, set_move_bb_top_left, set_move_bb_bottom_right, reset_move_bbs) from .points import PointSet @@ -98,7 +99,6 @@ def __handle_move_points(ctx, event): set_move_bb_bottom_right(event.x(), event.y()) - elif __left_click_flag and event.type() == QEvent.MouseButtonRelease: __left_click_flag = False @@ -106,12 +106,12 @@ def __handle_move_points(ctx, event): # Final bottom right corner point set_move_bb_bottom_right(event.x(), event.y()) - # Call the selection procedure - # TODO - # Satisfy the post condition by resetting the bounding box reset_move_bbs() + # Fix the highlighted pointed into a set (separate from point_set) and + # prepare to move. + # Find and move all points from the old list to their new locations ctx.opengl_widget.update() diff --git a/clusterview/opengl_widget.py b/clusterview/opengl_widget.py index 4241071..3348455 100644 --- a/clusterview/opengl_widget.py +++ b/clusterview/opengl_widget.py @@ -15,8 +15,8 @@ Probably even into it's own module folder. from enum import Enum -from OpenGL.GL import (glBegin, glClearColor, glColor4f, glEnable, - glEnd, GL_LIGHT0, GL_LIGHTING, GL_LINE_LOOP, GL_POINTS, +from OpenGL.GL import (glBegin, glClearColor, glColor3f, glEnable, + glEnd, GL_LINE_LOOP, GL_POINTS, glPointSize, glVertex3f, glViewport) from .exceptions import handle_exceptions, InvalidModeError, InvalidStateError @@ -26,12 +26,14 @@ from .points import PointSet class Color(Enum): BLUE = 0 BLACK = 1 + GREY = 2 # A simple map from Color -> RGBA 4-Tuple # Note: The color values in the tuple are not RGB, but # rather OpenGL percentage values for RGB. COLOR_TO_RGBA = { - Color.BLUE: (0, 0.5, 1.0, 0.0), + Color.GREY: (0.827, 0.827, 0.826, 0.0), + Color.BLUE: (0.118, 0.565, 1.0, 0.0), Color.BLACK: (0.0, 0.0, 0.0, 0.0) } @@ -151,6 +153,14 @@ def set_move_bb_bottom_right(x, y): __move_bb_bottom_right = (x, y) +def get_bb_top_left(): + return __move_bb_top_left + + +def get_bb_bottom_right(): + return __move_bb_bottom_right + + def reset_move_bbs(): global __move_bb_top_left global __move_bb_bottom_right @@ -163,10 +173,6 @@ def initialize_gl(): """ Initializes the OpenGL context on the Window. """ - # Since we aren't using shaders lighting needs to be - # enabled. - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); # Set white background glClearColor(255, 255, 255, 0) @@ -208,7 +214,7 @@ def paint_gl(): # the point set, which will be redrawn here. This action # is the same as adding a point since we just draw what is in # the point set. - draw_points(__current_points, Color.BLUE) + draw_points(__current_points, Color.GREY) elif __current_mode is Mode.EDIT: raise NotImplementedError("Drawing for EDIT not implemented.") @@ -217,16 +223,21 @@ def paint_gl(): # We have to repeatedly draw the points while we are showing the # move box. if __current_points is not None: - draw_points(__current_points, Color.BLUE) + draw_points(__current_points, Color.GREY) + + draw_selection_box(Color.BLACK) - draw_selection_box(Color.BLACK) + if (__move_bb_top_left is not None and + __move_bb_bottom_right is not None): + + highlight_selection() if __move_bb_top_left is None and __move_bb_bottom_right is None: # Currently this fires all the time - not great. Needs to only fire # when, additionally, we have a selection chosen based on the box # calculated in the mode handlers. + None - print("FIRE THE MOVE STUFF") # Once the selection boxes go to None begin the highlight selected # points procedure. This will store a point list of selected points # highlight them, etc. @@ -260,6 +271,63 @@ def __clamp_y(y): return y_w +def box_hit(tx, ty, x1, y1, x2, y2): + """ + Calculates whether or not a given point collides with the given bounding + box. + + @param tx The target x. + @param ty The target y. + @param x1 The top left x. + @param y1 The top left y. + @param x2 The bottom left x. + @param y2 The bottom left y. + """ + return (tx >= x1 and + tx <= x2 and + ty >= y1 and + ty <= y2) + + +def highlight_selection(): + """ + Given the current move bounding box, highlights any points inside it. + """ + + # TODO: There's an edge case here + # The edge case is that if you click and drag up top_left becomes + # bottom right so there must be a condition where they should be + # swapped. + top_left = get_bb_top_left() + bottom_right = get_bb_bottom_right() + + ct = COLOR_TO_RGBA[Color.BLUE] + + glBegin(GL_POINTS) + glColor3f(ct[0], ct[1], ct[2]) + for point in __current_points.points: + if box_hit(point.x, point.y, top_left[0], top_left[1], + bottom_right[0], bottom_right[1]): + + # Paint the point and draw over it. + # TODO: After the mouse drag drop these highlighted points should be + # stored in a move set. Make sure to update these in a set + # dropping each as it doesn't make the hit condition anymore. + # + # + # TODO: Demonstrating movement might be difficult... come up with a + # good way on paper. + # + # + # TODO: The highlight any direction bug needs to be fixed but it + # works, you need an algorithm for storing points selected, + # painting them permanently, and then moving them as the + # mouse drags. + glVertex3f(__clamp_x(point.x), + __clamp_y(point.y), + 0.0) + glEnd() + def draw_selection_box(color): """ When the move bounding box state is populated and the mode is set @@ -294,7 +362,7 @@ def draw_selection_box(color): glBegin(GL_LINE_LOOP) - glColor4f(ct[0], ct[1], ct[2], ct[3]) + glColor3f(ct[0], ct[1], ct[2]) glVertex3f(__clamp_x(__move_bb_top_left[0]), __clamp_y(__move_bb_top_left[1]), @@ -341,11 +409,9 @@ def draw_points(point_set, color): glBegin(GL_POINTS) - glColor4f(ct[0], ct[1], ct[2], ct[3]) + glColor3f(ct[0], ct[1], ct[2]) for point in point_set.points: glVertex3f(__clamp_x(point.x), __clamp_y(point.y), 0.0) # Z is currently fixed to 0 glEnd() - -