blob: 26b2cb23fbb145e4fe24f1d7c528d13f13a997e2 [file] [log] [blame]
Tabitha Jarvis1007a132018-12-12 21:47:54 -08001#!/usr/bin/python3
Tabitha Jarvis1007a132018-12-12 21:47:54 -08002from __future__ import print_function
3import os
Andrew Runke0f945fd2019-01-27 21:10:37 -08004import sys
Andrew Runke6842bf92019-01-26 15:38:25 -08005import copy
Tabitha Jarvis1007a132018-12-12 21:47:54 -08006import basic_window
7from color import Color, palette
8import random
9import gi
10import numpy as np
Andrew Runke6842bf92019-01-26 15:38:25 -080011from libspline import Spline
Tabitha Jarvis1007a132018-12-12 21:47:54 -080012import scipy.spatial.distance
13gi.require_version('Gtk', '3.0')
Andrew Runke6842bf92019-01-26 15:38:25 -080014from gi.repository import Gdk, Gtk, GLib
Tabitha Jarvis1007a132018-12-12 21:47:54 -080015import cairo
Tabitha Jarvis1007a132018-12-12 21:47:54 -080016import enum
Andrew Runke0f945fd2019-01-27 21:10:37 -080017import json # For writing to json files
Tabitha Jarvis1007a132018-12-12 21:47:54 -080018
19from basic_window import OverrideMatrix, identity, quit_main_loop, set_color
20
John Park13d3e282019-01-26 20:16:48 -080021WIDTH_OF_FIELD_IN_METERS = 8.258302
Tabitha Jarvis1007a132018-12-12 21:47:54 -080022PIXELS_ON_SCREEN = 300
23
Andrew Runke6842bf92019-01-26 15:38:25 -080024
John Park13d3e282019-01-26 20:16:48 -080025def pxToM(p):
26 return p * WIDTH_OF_FIELD_IN_METERS / PIXELS_ON_SCREEN
Andrew Runke6842bf92019-01-26 15:38:25 -080027
Tabitha Jarvis1007a132018-12-12 21:47:54 -080028
John Park13d3e282019-01-26 20:16:48 -080029def mToPx(i):
30 return (i * PIXELS_ON_SCREEN / WIDTH_OF_FIELD_IN_METERS)
Andrew Runke6842bf92019-01-26 15:38:25 -080031
Tabitha Jarvis1007a132018-12-12 21:47:54 -080032
33def px(cr):
34 return OverrideMatrix(cr, identity)
35
Andrew Runke6842bf92019-01-26 15:38:25 -080036
Tabitha Jarvis1007a132018-12-12 21:47:54 -080037def draw_px_cross(cr, x, y, length_px, color=palette["RED"]):
38 """Draws a cross with fixed dimensions in pixel space."""
39 set_color(cr, color)
40 cr.move_to(x, y - length_px)
41 cr.line_to(x, y + length_px)
42 cr.stroke()
43
44 cr.move_to(x - length_px, y)
45 cr.line_to(x + length_px, y)
46 cr.stroke()
47 set_color(cr, palette["LIGHT_GREY"])
48
Andrew Runke6842bf92019-01-26 15:38:25 -080049
Tabitha Jarvis1007a132018-12-12 21:47:54 -080050def draw_px_x(cr, x, y, length_px1, color=palette["BLACK"]):
51 """Draws a x with fixed dimensions in pixel space."""
52 length_px = length_px1 / np.sqrt(2)
53 set_color(cr, color)
54 cr.move_to(x - length_px, y - length_px)
55 cr.line_to(x + length_px, y + length_px)
56 cr.stroke()
57
58 cr.move_to(x - length_px, y + length_px)
59 cr.line_to(x + length_px, y - length_px)
60 cr.stroke()
61 set_color(cr, palette["LIGHT_GREY"])
62
Andrew Runke6842bf92019-01-26 15:38:25 -080063
Tabitha Jarvis1007a132018-12-12 21:47:54 -080064def draw_points(cr, p, size):
65 for i in range(0, len(p)):
Andrew Runke6842bf92019-01-26 15:38:25 -080066 draw_px_cross(cr, p[i][0], p[i][1], size, Color(
67 0, np.sqrt(0.2 * i), 0))
68
Tabitha Jarvis1007a132018-12-12 21:47:54 -080069
70class Mode(enum.Enum):
71 kViewing = 0
72 kPlacing = 1
73 kEditing = 2
74 kExporting = 3
75 kImporting = 4
Andrew Runke6842bf92019-01-26 15:38:25 -080076 kConstraint = 5
77
78
79class ConstraintType(enum.Enum):
80 kMaxSpeed = 0
81 kMaxAcceleration = 1
82
Tabitha Jarvis1007a132018-12-12 21:47:54 -080083
84def display_text(cr, text, widtha, heighta, widthb, heightb):
85 cr.scale(widtha, -heighta)
86 cr.show_text(text)
87 cr.scale(widthb, -heightb)
88
Andrew Runke6842bf92019-01-26 15:38:25 -080089
90def redraw(needs_redraw, window):
91 print("Redrew")
92 if not needs_redraw:
93 window.queue_draw()
94
95
96class Constraint():
97 def __init__(self, start, end, constraint, value):
98 self.start = start #Array with index and distance from start of spline
99 self.end = end #Array with index and distance from start of spline
100 self.constraint = constraint #INT
101 self.value = value #INT
102 if self.constraint == 0:
103 self.conName = "kMaxSpeed"
104 else:
105 self.conName = "kMaxAcceleration"
106
107 def toString(self):
108
109 return "START: " + str(self.start[0]) + ", " + str(
110 self.start[1]) + " | END: " + str(self.end[0]) + ", " + str(
111 self.end[1]) + " | " + str(self.conName) + ": " + str(
112 self.value)
113
114
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800115class GTK_Widget(basic_window.BaseWindow):
Andrew Runke6842bf92019-01-26 15:38:25 -0800116 """Create a GTK+ widget on which we will draw using Cairo"""
117
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800118 def __init__(self):
119 super(GTK_Widget, self).__init__()
120
121 # init field drawing
122 # add default spline for testing purposes
123 # init editing / viewing modes and pointer location
124 self.mode = Mode.kPlacing
125 self.x = 0
126 self.y = 0
127
Andrew Runke0f945fd2019-01-27 21:10:37 -0800128 module_path = os.path.dirname(os.path.realpath(sys.argv[0]))
129 self.path_to_export = os.path.join(module_path,
130 'points_for_pathedit.json')
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800131 # update list of control points
132 self.point_selected = False
133 # self.adding_spline = False
134 self.index_of_selected = -1
135 self.new_point = []
136
137 # For the editing mode
Andrew Runke6842bf92019-01-26 15:38:25 -0800138 self.index_of_edit = -1 # Can't be zero beause array starts at 0
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800139 self.held_x = 0
Andrew Runke6842bf92019-01-26 15:38:25 -0800140 self.spline_edit = -1
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800141
Andrew Runke6842bf92019-01-26 15:38:25 -0800142 self.curves = []
143
144 self.colors = []
145
146 for c in palette:
147 self.colors.append(palette[c])
148
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800149 self.selected_points = []
Andrew Runke6842bf92019-01-26 15:38:25 -0800150 self.splines = []
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800151 self.reinit_extents()
152
Andrew Runke6842bf92019-01-26 15:38:25 -0800153 self.inStart = None
154 self.inEnd = None
155 self.inConstraint = None
156 self.inValue = None
157 self.startSet = False
158
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800159 #John also wrote this
160 def add_point(self, x, y):
Andrew Runke6842bf92019-01-26 15:38:25 -0800161 if (len(self.selected_points) < 6):
John Park13d3e282019-01-26 20:16:48 -0800162 self.selected_points.append([pxToM(x), pxToM(y)])
Andrew Runke6842bf92019-01-26 15:38:25 -0800163 if (len(self.selected_points) == 6):
164 self.mode = Mode.kEditing
165 self.splines.append(np.array(self.selected_points))
166 self.selected_points = []
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800167
Andrew Runke6842bf92019-01-26 15:38:25 -0800168 """set extents on images"""
169
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800170 def reinit_extents(self):
171 self.extents_x_min = -800
172 self.extents_x_max = 800
173 self.extents_y_min = -800
174 self.extents_y_max = 800
175
176 # this needs to be rewritten with numpy, i dont think this ought to have
177 # SciPy as a dependecy
178 def get_index_of_nearest_point(self):
179 cur_p = [[self.x, self.y]]
180 distances = scipy.spatial.distance.cdist(cur_p, self.all_controls)
181
182 return np.argmin(distances)
183
184 # return the closest point to the loc of the click event
185 def get_nearest_point(self):
186 return self.all_controls[self.get_index_of_nearest_point()]
187
Andrew Runke6842bf92019-01-26 15:38:25 -0800188 def set_index_to_nearest_spline_point(self):
189 nearest = 50
190 index_of_closest = 0
191 self.spline_edit = 0
192 cur_p = [self.x, self.y]
193
194 for index_splines, points in enumerate(self.spline):
John Park13d3e282019-01-26 20:16:48 -0800195 for index_points, point in enumerate(points.curve):
Andrew Runke6842bf92019-01-26 15:38:25 -0800196 # pythagorean
John Park13d3e282019-01-26 20:16:48 -0800197 distance = np.sqrt((cur_p[0] - mToPx(point[0]))**2 +
198 (cur_p[1] - mToPx(point[1])**2))
Andrew Runke6842bf92019-01-26 15:38:25 -0800199 if distance < nearest:
200 nearest = distance
201 print("DISTANCE: ", distance, " | INDEX: ", index_points)
202 index_of_closest = index_points
203 self.index_of_edit = index_of_closest
204 self.spline_edit = index_splines
205 self.held_x = self.x
206 if self.startSet == False:
207 self.inStart = [self.index_of_edit, self.findDistance()]
208 self.startSet = True
209 else:
210 self.inEnd = [self.index_of_edit, self.findDistance()]
Andrew Runke6842bf92019-01-26 15:38:25 -0800211 self.startSet = False
212 self.mode = Mode.kEditing
213 self.spline_edit = -1
214 self.index_of_edit = -1
215
216 print("Nearest: " + str(nearest))
217 print("Spline: " + str(self.spline_edit))
218 print("Index: " + str(index_of_closest))
219
220 def findDistance(self):
221 """ findDistance goes through each point on the spline finding distance to that point from the point before.
222 It does this to find the the length of the spline to the point that is currently selected.
223 """
224 distance = 0
225 points = self.curves[self.spline_edit]
226 for index, point in enumerate(points):
227 if index > 0 and index <= self.index_of_edit:
228 distance += np.sqrt((points[index - 1][0] - point[0])**2 +
229 (points[index - 1][1] - point[1])**2)
John Park13d3e282019-01-26 20:16:48 -0800230 return distance
Andrew Runke6842bf92019-01-26 15:38:25 -0800231
232 # Handle the expose-event by updating the Window and drawing
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800233 def handle_draw(self, cr):
Andrew Runke6842bf92019-01-26 15:38:25 -0800234 # print(self.new_point)
235 # print("SELF.POINT_SELECTED: " + str(self.point_selected))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800236
237 # begin drawing
238 # Fill the background color of the window with grey
239 set_color(cr, palette["GREY"])
240 cr.paint()
Andrew Runkea9c8de52019-01-26 19:54:29 -0800241 #Scale the field to fit within drawing area
Andrew Runke6696bb82019-02-02 14:33:59 -0800242 cr.scale(0.5, 0.5)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800243
244 # Draw a extents rectangle
245 set_color(cr, palette["WHITE"])
246 cr.rectangle(self.extents_x_min, self.extents_y_min,
247 (self.extents_x_max - self.extents_x_min),
248 self.extents_y_max - self.extents_y_min)
249 cr.fill()
250
251 #Drawing the switch and scale in the field
252 cr.move_to(0, 50)
253 cr.show_text('Press "e" to export')
254 cr.show_text('Press "i" to import')
255
256 set_color(cr, Color(0.3, 0.3, 0.3))
Andrew Runke6842bf92019-01-26 15:38:25 -0800257 cr.rectangle(-450, -150, 300, 300)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800258 cr.fill()
259 set_color(cr, palette["BLACK"])
Andrew Runke6842bf92019-01-26 15:38:25 -0800260 cr.rectangle(-450, -150, 300, 300)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800261 cr.set_line_join(cairo.LINE_JOIN_ROUND)
262 cr.stroke()
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800263
Andrew Runke6842bf92019-01-26 15:38:25 -0800264 y = 0
Andrew Runke6842bf92019-01-26 15:38:25 -0800265
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800266 # update all the things
267
268 if self.mode == Mode.kViewing:
269 set_color(cr, palette["BLACK"])
270 cr.move_to(-300, 170)
271 cr.show_text("VIEWING")
272 set_color(cr, palette["GREY"])
Andrew Runke6842bf92019-01-26 15:38:25 -0800273
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800274 if len(self.selected_points) > 0:
275 print("SELECTED_POINTS: " + str(len(self.selected_points)))
276 print("ITEMS:")
Andrew Runke6842bf92019-01-26 15:38:25 -0800277 # for item in self.selected_points:
278 # print(str(item))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800279 for i, point in enumerate(self.selected_points):
Andrew Runke6842bf92019-01-26 15:38:25 -0800280 # print("I: " + str(i))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800281 draw_px_x(cr, point[0], point[1], 10)
Andrew Runke6842bf92019-01-26 15:38:25 -0800282 cr.move_to(point[0], point[1] - 15)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800283 display_text(cr, str(i), 0.5, 0.5, 2, 2)
284
Andrew Runke6842bf92019-01-26 15:38:25 -0800285 elif self.mode == Mode.kPlacing:
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800286 set_color(cr, palette["BLACK"])
287 cr.move_to(-300, 170)
288 display_text(cr, "ADD", 1, 1, 1, 1)
289 set_color(cr, palette["GREY"])
Andrew Runke6842bf92019-01-26 15:38:25 -0800290
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800291 if len(self.selected_points) > 0:
292 print("SELECTED_POINTS: " + str(len(self.selected_points)))
293 print("ITEMS:")
294 for item in self.selected_points:
295 print(str(item))
296 for i, point in enumerate(self.selected_points):
297 print("I: " + str(i))
John Park13d3e282019-01-26 20:16:48 -0800298 draw_px_x(cr, mToPx(point[0]), mToPx(point[1]), 10)
299 cr.move_to(mToPx(point[0]), mToPx(point[1]) - 15)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800300 display_text(cr, str(i), 0.5, 0.5, 2, 2)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800301
302 elif self.mode == Mode.kEditing:
303 set_color(cr, palette["BLACK"])
304 cr.move_to(-300, 170)
305 display_text(cr, "EDITING", 1, 1, 1, 1)
Andrew Runke6842bf92019-01-26 15:38:25 -0800306 if len(self.splines) > 0:
Andrew Runke6842bf92019-01-26 15:38:25 -0800307 holder_spline = []
308 for i, points in enumerate(self.splines):
309 array = np.zeros(shape=(6, 2), dtype=float)
310 for j, point in enumerate(points):
John Park13d3e282019-01-26 20:16:48 -0800311 array[j, 0] = mToPx(point[0])
312 array[j, 1] = mToPx(point[1])
Andrew Runke6842bf92019-01-26 15:38:25 -0800313 spline = Spline(np.ascontiguousarray(np.transpose(array)))
314 for k in np.linspace(0.01, 1, 100):
Andrew Runke6842bf92019-01-26 15:38:25 -0800315 cr.move_to(
316 spline.Point(k - 0.01)[0],
317 spline.Point(k - 0.01)[1])
318 cr.line_to(spline.Point(k)[0], spline.Point(k)[1])
319 cr.stroke()
320 holding = [
321 spline.Point(k - 0.01)[0],
322 spline.Point(k - 0.01)[1]
323 ]
Andrew Runke6842bf92019-01-26 15:38:25 -0800324 holder_spline.append(holding)
325 self.curves.append(holder_spline)
326
327 for spline, points in enumerate(self.splines):
328 # for item in points:
329 # print(str(item))
330 for i, point in enumerate(points):
331 # print("I: " + str(i))
332 if spline == self.spline_edit and i == self.index_of_edit:
John Park13d3e282019-01-26 20:16:48 -0800333 draw_px_x(cr, mToPx(point[0]), mToPx(point[1]), 15,
Andrew Runke6842bf92019-01-26 15:38:25 -0800334 self.colors[spline])
335 elif (spline == 0 and not i == 5) or (not i == 0
336 and not i == 5):
John Park13d3e282019-01-26 20:16:48 -0800337 draw_px_x(cr, mToPx(point[0]), mToPx(point[1]), 10,
Andrew Runke6842bf92019-01-26 15:38:25 -0800338 self.colors[spline])
John Park13d3e282019-01-26 20:16:48 -0800339 cr.move_to(mToPx(point[0]), mToPx(point[1]) - 15)
Andrew Runke6842bf92019-01-26 15:38:25 -0800340 display_text(cr, str(i), 0.5, 0.5, 2, 2)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800341
Andrew Runke6842bf92019-01-26 15:38:25 -0800342 elif self.mode == Mode.kConstraint:
343 print("Drawn")
344 set_color(cr, palette["BLACK"])
345 cr.move_to(-300, 170)
346 display_text(cr, "Adding Constraint", 1, 1, 1, 1)
347 if len(self.splines) > 0:
348 # print("Splines: " + str(len(self.splines)))
349 # print("ITEMS:")
350 for s, points in enumerate(self.splines):
351 # for item in points:
352 # print(str(item))
353 for i, point in enumerate(points):
354 # print("I: " + str(i))
355 draw_px_x(cr, point[0], point[1], 10, self.colors[s])
356 cr.move_to(point[0], point[1] - 15)
357 display_text(cr, str(i), 0.5, 0.5, 2, 2)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800358
359 cr.paint_with_alpha(.65)
360
361 draw_px_cross(cr, self.x, self.y, 10)
362
363 def do_key_press(self, event):
364 keyval = Gdk.keyval_to_lower(event.keyval)
Andrew Runke6842bf92019-01-26 15:38:25 -0800365 # print("Gdk.KEY_" + Gdk.keyval_name(keyval))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800366 if keyval == Gdk.KEY_q:
367 print("Found q key and exiting.")
368 quit_main_loop()
369 if keyval == Gdk.KEY_e:
Andrew Runke0f945fd2019-01-27 21:10:37 -0800370 # Will export to json file
371 self.mode = Mode.kEditing
372 print(str(sys.argv))
373 print('out to: ', self.path_to_export)
374 exportList = [l.tolist() for l in self.splines]
375 with open(self.path_to_export, mode='w') as points_file:
376 json.dump(exportList, points_file)
377 print("Wrote: " + str(self.splines))
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800378 if keyval == Gdk.KEY_i:
Andrew Runke0f945fd2019-01-27 21:10:37 -0800379 # import from json file
380 self.mode = Mode.kEditing
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800381 self.selected_points = []
Andrew Runke0f945fd2019-01-27 21:10:37 -0800382 self.splines = []
383 with open(self.path_to_export) as points_file:
384 self.splines = json.load(points_file)
385 print("Added: " + str(self.splines))
Andrew Runke6842bf92019-01-26 15:38:25 -0800386 if keyval == Gdk.KEY_p:
387 self.mode = Mode.kPlacing
388 # F0 = A1
389 # B1 = 2F0 - E0
390 # C1= d0 + 4F0 - 4E0
391 spline_index = len(self.splines) - 1
392 self.selected_points = []
393 f = self.splines[spline_index][5]
394 e = self.splines[spline_index][4]
395 d = self.splines[spline_index][3]
396 self.selected_points.append(f)
397 self.selected_points.append(f * 2 + e * -1)
398 self.selected_points.append(d + f * 4 + e * -4)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800399
Andrew Runke6842bf92019-01-26 15:38:25 -0800400 if keyval == Gdk.KEY_c:
401 self.mode = Mode.kConstraint
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800402
403 def button_press_action(self):
Andrew Runke6842bf92019-01-26 15:38:25 -0800404 if self.mode == Mode.kPlacing:
405 #Check that the point clicked is on the field
406 if (self.x < -150 and self.x > -450 and self.y < 150
407 and self.y > -150):
408 self.add_point(self.x, self.y)
409 elif self.mode == Mode.kEditing:
410 # Now after index_of_edit is not -1, the point is selected, so
411 # user can click for new point
412 if self.index_of_edit > -1 and self.held_x != self.x:
413 print("INDEX OF EDIT: " + str(self.index_of_edit))
414 self.splines[self.spline_edit][self.index_of_edit] = [
John Park13d3e282019-01-26 20:16:48 -0800415 pxToM(self.x), pxToM(self.y)
Andrew Runke6842bf92019-01-26 15:38:25 -0800416 ]
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800417
Andrew Runke6842bf92019-01-26 15:38:25 -0800418 if not self.spline_edit == len(self.splines) - 1:
419 spline_edit = self.spline_edit + 1
420 f = self.splines[self.spline_edit][5]
421 e = self.splines[self.spline_edit][4]
422 d = self.splines[self.spline_edit][3]
423 self.splines[spline_edit][0] = f
424 self.splines[spline_edit][1] = f * 2 + e * -1
425 self.splines[spline_edit][2] = d + f * 4 + e * -4
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800426
Andrew Runke6842bf92019-01-26 15:38:25 -0800427 if not self.spline_edit == 0:
428 spline_edit = self.spline_edit - 1
429 a = self.splines[self.spline_edit][0]
430 b = self.splines[self.spline_edit][1]
431 c = self.splines[self.spline_edit][2]
432 self.splines[spline_edit][5] = a
433 self.splines[spline_edit][4] = a * 2 + b * -1
434 self.splines[spline_edit][3] = c + a * 4 + b * -4
435
Andrew Runke6842bf92019-01-26 15:38:25 -0800436 self.index_of_edit = -1
437 self.spline_edit = -1
438 else:
439 print("mode == 2")
440 # Get clicked point
441 # Find nearest
442 # Move nearest to clicked
John Park13d3e282019-01-26 20:16:48 -0800443 cur_p = [pxToM(self.x), pxToM(self.y)]
Andrew Runke6842bf92019-01-26 15:38:25 -0800444 print("CUR_P: " + str(self.x) + " " + str(self.y))
445 # Get the distance between each for x and y
446 # Save the index of the point closest
John Park13d3e282019-01-26 20:16:48 -0800447 nearest = 1 # Max distance away a the selected point can be in meters
Andrew Runke6842bf92019-01-26 15:38:25 -0800448 index_of_closest = 0
449 for index_splines, points in enumerate(self.splines):
450 for index_points, val in enumerate(points):
451 # pythagorean
452 distance = np.sqrt((cur_p[0] - val[0])**2 +
453 (cur_p[1] - val[1])**2)
454 if distance < nearest:
455 nearest = distance
456 index_of_closest = index_points
457 print("Nearest: " + str(nearest))
458 print("Index: " + str(index_of_closest))
459 self.index_of_edit = index_of_closest
460 self.spline_edit = index_splines
461 self.held_x = self.x
462 elif self.mode == Mode.kConstraint:
463 print("RAN")
464 self.set_index_to_nearest_spline_point()
465 print("FINISHED")
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800466
467 def do_button_press(self, event):
468 print("button press activated")
John Park13d3e282019-01-26 20:16:48 -0800469 # Be consistent with the scaling in the drawing_area
Andrew Runkea9c8de52019-01-26 19:54:29 -0800470 self.x = event.x * 2
471 self.y = event.y * 2
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800472 self.button_press_action()
473
474
Andrew Runke6842bf92019-01-26 15:38:25 -0800475class GridWindow(Gtk.Window):
476 def method_connect(self, event, cb):
477 def handler(obj, *args):
478 cb(*args)
Tabitha Jarvis1007a132018-12-12 21:47:54 -0800479
Andrew Runke6842bf92019-01-26 15:38:25 -0800480 print("Method_connect ran")
481 self.connect(event, handler)
482
483 def button_press(self, event):
484 print("button press activated")
485 o_x = event.x
486 o_y = event.y
487 x = event.x - self.drawing_area.window_shape[0] / 2
488 y = self.drawing_area.window_shape[1] / 2 - event.y
489 scale = self.drawing_area.get_current_scale()
490 event.x = x / scale + self.drawing_area.center[0]
491 event.y = y / scale + self.drawing_area.center[1]
492 self.drawing_area.do_button_press(event)
493 event.x = o_x
494 event.y = o_y
495
496 def key_press(self, event):
497 print("key press activated")
498 self.drawing_area.do_key_press(event)
499 self.queue_draw()
500
501 def configure(self, event):
502 print("configure activated")
503 self.drawing_area.window_shape = (event.width, event.height)
504
505 def on_submit_click(self, widget):
506 self.drawing_area.inConstraint = int(self.constraint_box.get_text())
507 self.drawing_area.inValue = int(self.value_box.get_text())
508
509 def __init__(self):
510 Gtk.Window.__init__(self)
511
512 self.set_default_size(1366, 738)
513
514 flowBox = Gtk.FlowBox()
515 flowBox.set_valign(Gtk.Align.START)
516 flowBox.set_selection_mode(Gtk.SelectionMode.NONE)
517
518 flowBox.set_valign(Gtk.Align.START)
519
520 self.add(flowBox)
521
522 container = Gtk.Fixed()
523 flowBox.add(container)
524
525 self.eventBox = Gtk.EventBox()
526 container.add(self.eventBox)
527
528 self.eventBox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK
529 | Gdk.EventMask.BUTTON_RELEASE_MASK
530 | Gdk.EventMask.POINTER_MOTION_MASK
531 | Gdk.EventMask.SCROLL_MASK
532 | Gdk.EventMask.KEY_PRESS_MASK)
533
534 self.drawing_area = GTK_Widget()
535 self.eventBox.add(self.drawing_area)
536
537 self.method_connect("key-release-event", self.key_press)
538 self.method_connect("button-release-event", self.button_press)
539 self.method_connect("configure-event", self.configure)
540
541 # Constraint Boxes
542
543 self.start_box = Gtk.Entry()
544 self.start_box.set_size_request(100, 20)
545
546 self.constraint_box = Gtk.Entry()
547 self.constraint_box.set_size_request(100, 20)
548
549 self.constraint_box.set_text("Constraint")
550 self.constraint_box.set_editable(True)
551
552 container.put(self.constraint_box, 700, 0)
553
554 self.value_box = Gtk.Entry()
555 self.value_box.set_size_request(100, 20)
556
557 self.value_box.set_text("Value")
558 self.value_box.set_editable(True)
559
560 container.put(self.value_box, 700, 40)
561
562 self.submit_button = Gtk.Button("Submit")
563 self.submit_button.connect('clicked', self.on_submit_click)
564
565 container.put(self.submit_button, 880, 0)
566
567 self.show_all()
568
569
570window = GridWindow()
John Park13d3e282019-01-26 20:16:48 -0800571basic_window.RunApp()