Combine ArmUi and segment selector
This was done to make future additions to the ArmUi
easier to create
Signed-off-by: Maxwell Henderson <mxwhenderson@gmail.com>
Change-Id: I4de2d56eacfabe1d7bfe5b025636b6e6c82ed690
diff --git a/y2023/control_loops/python/graph_edit.py b/y2023/control_loops/python/graph_edit.py
index 37e951f..75e3cb8 100644
--- a/y2023/control_loops/python/graph_edit.py
+++ b/y2023/control_loops/python/graph_edit.py
@@ -23,6 +23,8 @@
import shapely
from shapely.geometry import Polygon
+from frc971.control_loops.python.constants import *
+
def px(cr):
return OverrideMatrix(cr, identity)
@@ -228,29 +230,19 @@
# Create a GTK+ widget on which we will draw using Cairo
-class ArmUi(basic_window.BaseWindow):
+class ArmUi(Gtk.DrawingArea):
def __init__(self, segments):
super(ArmUi, self).__init__()
- self.window = Gtk.Window()
- self.window.set_title("DrawingArea")
-
- self.window.set_events(Gdk.EventMask.BUTTON_PRESS_MASK
- | Gdk.EventMask.BUTTON_RELEASE_MASK
- | Gdk.EventMask.POINTER_MOTION_MASK
- | Gdk.EventMask.SCROLL_MASK
- | Gdk.EventMask.KEY_PRESS_MASK)
- self.method_connect("key-press-event", self.do_key_press)
- self.method_connect("motion-notify-event", self.do_motion)
- self.method_connect("button-press-event",
- self._do_button_press_internal)
- self.method_connect("configure-event", self._do_configure)
- self.window.add(self)
- self.window.show_all()
-
+ self.set_size_request(2 * SCREEN_SIZE, SCREEN_SIZE)
+ self.center = (0, 0)
+ self.shape = (2 * SCREEN_SIZE, SCREEN_SIZE)
self.theta_version = False
- self.reinit_extents()
+
+ self.init_extents()
+
+ self.connect('draw', self.on_draw)
self.last_pos = to_xy(*graph_paths.points['Neutral'][:2])
self.circular_index_select = 1
@@ -282,18 +274,20 @@
[DRIVER_CAM_X, DRIVER_CAM_Y],
DRIVER_CAM_WIDTH, DRIVER_CAM_HEIGHT)
- self.segment_selector = SegmentSelector(self.segments)
- self.segment_selector.show()
-
self.show_indicators = True
# Lets you only view selected path
self.view_current = False
self.editing = True
+ self.x_offset = 0
+ self.y_offset = 0
+
def _do_button_press_internal(self, event):
o_x = event.x
o_y = event.y
+ event.y -= self.y_offset
+ event.x -= self.x_offset
x = event.x - self.window_shape[0] / 2
y = self.window_shape[1] / 2 - event.y
scale = self.get_current_scale()
@@ -306,19 +300,7 @@
def _do_configure(self, event):
self.window_shape = (event.width, event.height)
- def redraw(self):
- if not self.needs_redraw:
- self.needs_redraw = True
- self.window.queue_draw()
-
- def method_connect(self, event, cb):
-
- def handler(obj, *args):
- cb(*args)
-
- self.window.connect(event, handler)
-
- def reinit_extents(self):
+ def init_extents(self):
if self.theta_version:
self.extents_x_min = -np.pi * 2
self.extents_x_max = np.pi * 2
@@ -330,18 +312,41 @@
self.extents_y_min = -4.0 * 0.0254
self.extents_y_max = 110.0 * 0.0254
- self.init_extents(
- (0.5 * (self.extents_x_min + self.extents_x_max), 0.5 *
- (self.extents_y_max + self.extents_y_min)),
- (1.0 * (self.extents_x_max - self.extents_x_min), 1.0 *
- (self.extents_y_max - self.extents_y_min)))
+ self.center = (0.5 * (self.extents_x_min + self.extents_x_max),
+ 0.5 * (self.extents_y_max + self.extents_y_min))
+ self.shape = (1.0 * (self.extents_x_max - self.extents_x_min),
+ 1.0 * (self.extents_y_max - self.extents_y_min))
+
+ def get_current_scale(self):
+ w_w, w_h = self.window_shape
+ w, h = self.shape
+ return min((w_w / w), (w_h / h))
+
+ def on_draw(self, widget, event):
+ cr = self.get_window().cairo_create()
+
+ self.window_shape = (self.get_window().get_geometry().width,
+ self.get_window().get_geometry().height)
+
+ cr.save()
+ cr.set_font_size(20)
+ cr.translate(self.window_shape[0] / 2, self.window_shape[1] / 2)
+ scale = self.get_current_scale()
+ cr.scale(scale, -scale)
+ cr.translate(-self.center[0], -self.center[1])
+ cr.reset_clip()
+ self.handle_draw(cr)
+ cr.restore()
+
+ def method_connect(self, event, cb):
+
+ def handler(obj, *args):
+ cb(*args)
+
+ self.window.connect(event, handler)
# Handle the expose-event by drawing
def handle_draw(self, cr):
- # use "with px(cr): blah;" to transform to pixel coordinates.
- if self.segment_selector.current_path_index is not None:
- self.index = self.segment_selector.current_path_index
-
# Fill the background color of the window with grey
set_color(cr, palette["GREY"])
cr.paint()
@@ -487,6 +492,8 @@
def do_motion(self, event):
o_x = event.x
o_y = event.y
+ event.x -= self.x_offset
+ event.y -= self.y_offset
x = event.x - self.window_shape[0] / 2
y = self.window_shape[1] / 2 - event.y
scale = self.get_current_scale()
@@ -517,7 +524,7 @@
event.x = o_x
event.y = o_y
- self.redraw()
+ self.queue_draw()
def do_key_press(self, event):
keyval = Gdk.keyval_to_lower(event.keyval)
@@ -593,7 +600,7 @@
self.last_pos = self.cur_pt_in_theta()
self.theta_version = not self.theta_version
- self.reinit_extents()
+ self.init_extents()
elif keyval == Gdk.KEY_z:
self.edit_control1 = not self.edit_control1
@@ -610,7 +617,7 @@
print("self.last_pos: ", self.last_pos, " ci: ",
self.circular_index_select)
- self.redraw()
+ self.queue_draw()
def do_button_press(self, event):
@@ -639,10 +646,71 @@
self.segments[self.index].Print(graph_paths.points)
- self.redraw()
+ self.queue_draw()
-arm_ui = ArmUi(graph_paths.segments)
-print('Starting with segment: ', arm_ui.segments[arm_ui.index].name)
-arm_ui.segments[arm_ui.index].Print(graph_paths.points)
+class Window(Gtk.Window):
+
+ def __init__(self, segments):
+ super().__init__(title="Drawing Area")
+
+ self.segment_store = Gtk.ListStore(int, str)
+
+ for i, segment in enumerate(segments):
+ self.segment_store.append([i, segment.name])
+
+ self.segment_box = Gtk.ComboBox.new_with_model_and_entry(
+ self.segment_store)
+ self.segment_box.connect("changed", self.on_combo_changed)
+ self.segment_box.set_entry_text_column(1)
+
+ self.arm_draw = ArmUi(segments)
+
+ self.arm_draw.y_offset = self.segment_box.get_allocation().width
+
+ print('Starting with segment: ',
+ self.arm_draw.segments[self.arm_draw.index].name)
+ self.arm_draw.segments[self.arm_draw.index].Print(graph_paths.points)
+
+ self.set_events(Gdk.EventMask.BUTTON_PRESS_MASK
+ | Gdk.EventMask.BUTTON_RELEASE_MASK
+ | Gdk.EventMask.POINTER_MOTION_MASK
+ | Gdk.EventMask.SCROLL_MASK
+ | Gdk.EventMask.KEY_PRESS_MASK)
+ self.method_connect('map-event', self.do_map_event)
+ self.method_connect("key-press-event", self.arm_draw.do_key_press)
+ self.method_connect("motion-notify-event", self.arm_draw.do_motion)
+ self.method_connect("button-press-event",
+ self.arm_draw._do_button_press_internal)
+ self.method_connect("configure-event", self.arm_draw._do_configure)
+
+ self.grid = Gtk.Grid()
+ self.add(self.grid)
+
+ self.grid.attach(self.arm_draw, 0, 1, 1, 1)
+
+ self.grid.attach(self.segment_box, 0, 0, 1, 1)
+
+ def on_combo_changed(self, combo):
+ iter = combo.get_active_iter()
+
+ if iter is not None:
+ model = combo.get_model()
+ id, name = model[iter][:2]
+ print("Selected: ID=%d, name=%s" % (id, name))
+ self.arm_draw.index = id
+
+ def method_connect(self, event, cb):
+
+ def handler(obj, *args):
+ cb(*args)
+
+ self.connect(event, handler)
+
+ def do_map_event(self, event):
+ self.arm_draw.y_offset = self.segment_box.get_allocation().height
+
+
+window = Window(graph_paths.segments)
+window.show_all()
basic_window.RunApp()