Module Auto-GUI.auto_components.movable_point
Expand source code
import tkinter
from miscellaneous import important_variables
from auto_components.grid_items import GridItems
from auto_components.input_field import InputField
from auto_features.data_validator import DataValidator
from auto_features.path_creation import get_hub_centric_coordinates
from miscellaneous.utility_functions import *
class MovablePoint(Button):
"""Any point that the user can move and modify the values of the fields (PathModifyingPoint, PathActionPoint, etc.)"""
# Miscellaneous
color = None
base_color = None
selected_color = None
user_modifiable_fields_grid = None
order_position_field = None
click_function = None
left_edge = 0
top_edge = 0
order_position = 0
left_edge_meters = 0
top_edge_meters = 0
# Alterable Data
user_modifiable_fields = []
left_edge_field = None
top_edge_field = None
order_position_field = None
# Size
base_length = get_measurement(SCREEN_LENGTH, .9)
base_height = base_length
base_modifiable_fields = []
is_needed = True
def __init__(self, base_color, selected_color, click_function, button_number):
"""Initializes the object"""
self.color, self.base_color = base_color, base_color
self.selected_color = selected_color
self.left_edge_field = InputField(WINDOW, SMALL_FONT, "0",
error_message_function=DataValidator.get_float_error_message_function(-9, 9))
self.top_edge_field = InputField(WINDOW, SMALL_FONT, "0",
error_message_function=DataValidator.get_float_error_message_function(-9, 9))
self.order_position_field = InputField(WINDOW, SMALL_FONT, "", is_editable=False)
self.user_modifiable_fields = [self.order_position_field, self.left_edge_field, self.top_edge_field]
self.base_modifiable_fields = [self.order_position_field, self.left_edge_field, self.top_edge_field]
self.click_function = click_function
super().__init__(WINDOW, bg=base_color, compound=tkinter.CENTER, command=lambda: click_function(self),
text=button_number, fg=white, font=MINISCULE_FONT)
#
# MAKE SURE THIS IS BEFORE PLACING
#
self.user_modifiable_fields_grid = GridItems(self.user_modifiable_fields, GridItems.horizontal_grid)
def point_user_alterable_fields(self):
"""
Returns:
GridItems: the grid containing all the user modifiable fields"""
return self.user_modifiable_fields_grid
def place(self, want_to_update_input_fields=False, **kwargs):
"""Places the object at that location (x, y, width, height)"""
self.left_edge = kwargs.get("x")
self.top_edge = kwargs.get("y")
if want_to_update_input_fields:
self.update_input_fields()
kwargs["x"] = int(self.left_edge)
kwargs["y"] = int(self.top_edge)
super().place(kwargs)
def __str__(self):
return str(id(self))
def default_update_coordinates(self):
"""Moves the component to where the input fields are saying it should be"""
field_top_edge = self.get_field_top_edge()
field_left_edge = self.get_field_left_edge()
left_edge_meters = self.get_field_left_edge()
top_edge_meters = self.get_field_top_edge()
top_edge_meters *= -1
left_edge_meters += important_variables.CENTER_OF_FIELD_HORIZONTAL_OFFSET
top_edge_meters += CENTER_OF_FIELD_VERTICAL_OFFSET
left_edge = meters_to_pixels(left_edge_meters)
top_edge = meters_to_pixels(top_edge_meters)
MovablePoint.place(self, x=left_edge, y=top_edge)
# So the coordinates do not change because of a rounding error
self.set_field_top_edge(field_top_edge)
self.set_field_left_edge(field_left_edge)
def update_input_fields(self):
"""Updates the input fields, so they reflect where the component is on the screen"""
left_edge = pixels_to_meters(self.left_edge)
top_edge = pixels_to_meters(self.top_edge)
left_edge, top_edge = get_hub_centric_coordinates(left_edge, top_edge)
self.set_field_left_edge(truncate(left_edge, INPUT_FIELD_DECIMAL_ACCURACY))
self.set_field_top_edge(truncate(top_edge, INPUT_FIELD_DECIMAL_ACCURACY))
# The reason these methods are needed is because the input field's sometimes have false data
def get_left_edge(self):
return self.left_edge
def get_top_edge(self):
return self.top_edge
def get_field_left_edge(self):
return float(self.left_edge_field.get_text())
def get_field_top_edge(self):
return float(self.top_edge_field.get_text())
def set_field_left_edge(self, value, want_rounding=False):
if want_rounding:
value = truncate(value, INPUT_FIELD_DECIMAL_ACCURACY)
self.left_edge_field.set_text(value)
def set_field_top_edge(self, value, want_rounding=False):
if want_rounding:
value = truncate(value, INPUT_FIELD_DECIMAL_ACCURACY)
self.top_edge_field.set_text(value)
def set_order_position(self, order_position):
"""Sets the position of the point (point #1, point #2, etc.)"""
self.configure(text=order_position)
self.order_position_field.set_text(order_position)
self.order_position = order_position
def destroy(self):
"""Overrides tkinter's method: removes the button and all the components of the button from the screen"""
for field in self.user_modifiable_fields:
field.destroy()
super().destroy()
def get_order_position(self):
"""
Returns:
int: the position of the point (point #1, point #2, etc.)"""
return self.order_position
def set_position_field_text(self, value):
self.order_position_field.configure(text=value)
def get_position_field_text(self):
return self.order_position_field.get_text()
def position_field_is_selected(self):
return self.order_position_field.is_selected
def get_input_fields(self):
"""
Returns:
InputField: all the input fields that this point has"""
return list(filter(lambda item: isinstance(item, InputField) and item.is_editable, self.user_modifiable_fields))
def get_user_modifiable_field(self):
"""
Returns:
list[object]: all the fields the user can modify"""
return self.user_modifiable_fields
def set_input_fields_command(self, command):
"""Makes all the input fields call the function 'command' when they are clicked"""
for input_field in self.get_input_fields():
input_field.set_command(command)
def update_input_fields_belongs_to(self):
"""So the Main Screen can know what the input field's belong to (a PathModifyingPoint for example)"""
for input_field in self.get_input_fields():
input_field.set_belongs_to(self)
def select(self):
"""Makes the point change to the selected color, so the user knows the point is selected"""
self.configure(bg=self.selected_color)
super().place(x=self.left_edge, y=self.top_edge, width=int(self.base_length * 1.5), height=int(self.base_height * 1.5))
def unselect(self):
"""Makes the point go back to the base color, so the user knows the point is not selected"""
self.configure(bg=self.base_color)
super().place(x=self.left_edge, y=self.top_edge, width=int(self.base_length), height=int(self.base_height))
def __str__(self):
"""FOR DEBUGGING"""
return str(self.get_field_top_edge())
Classes
class MovablePoint (base_color, selected_color, click_function, button_number)
-
Any point that the user can move and modify the values of the fields (PathModifyingPoint, PathActionPoint, etc.)
Initializes the object
Expand source code
class MovablePoint(Button): """Any point that the user can move and modify the values of the fields (PathModifyingPoint, PathActionPoint, etc.)""" # Miscellaneous color = None base_color = None selected_color = None user_modifiable_fields_grid = None order_position_field = None click_function = None left_edge = 0 top_edge = 0 order_position = 0 left_edge_meters = 0 top_edge_meters = 0 # Alterable Data user_modifiable_fields = [] left_edge_field = None top_edge_field = None order_position_field = None # Size base_length = get_measurement(SCREEN_LENGTH, .9) base_height = base_length base_modifiable_fields = [] is_needed = True def __init__(self, base_color, selected_color, click_function, button_number): """Initializes the object""" self.color, self.base_color = base_color, base_color self.selected_color = selected_color self.left_edge_field = InputField(WINDOW, SMALL_FONT, "0", error_message_function=DataValidator.get_float_error_message_function(-9, 9)) self.top_edge_field = InputField(WINDOW, SMALL_FONT, "0", error_message_function=DataValidator.get_float_error_message_function(-9, 9)) self.order_position_field = InputField(WINDOW, SMALL_FONT, "", is_editable=False) self.user_modifiable_fields = [self.order_position_field, self.left_edge_field, self.top_edge_field] self.base_modifiable_fields = [self.order_position_field, self.left_edge_field, self.top_edge_field] self.click_function = click_function super().__init__(WINDOW, bg=base_color, compound=tkinter.CENTER, command=lambda: click_function(self), text=button_number, fg=white, font=MINISCULE_FONT) # # MAKE SURE THIS IS BEFORE PLACING # self.user_modifiable_fields_grid = GridItems(self.user_modifiable_fields, GridItems.horizontal_grid) def point_user_alterable_fields(self): """ Returns: GridItems: the grid containing all the user modifiable fields""" return self.user_modifiable_fields_grid def place(self, want_to_update_input_fields=False, **kwargs): """Places the object at that location (x, y, width, height)""" self.left_edge = kwargs.get("x") self.top_edge = kwargs.get("y") if want_to_update_input_fields: self.update_input_fields() kwargs["x"] = int(self.left_edge) kwargs["y"] = int(self.top_edge) super().place(kwargs) def __str__(self): return str(id(self)) def default_update_coordinates(self): """Moves the component to where the input fields are saying it should be""" field_top_edge = self.get_field_top_edge() field_left_edge = self.get_field_left_edge() left_edge_meters = self.get_field_left_edge() top_edge_meters = self.get_field_top_edge() top_edge_meters *= -1 left_edge_meters += important_variables.CENTER_OF_FIELD_HORIZONTAL_OFFSET top_edge_meters += CENTER_OF_FIELD_VERTICAL_OFFSET left_edge = meters_to_pixels(left_edge_meters) top_edge = meters_to_pixels(top_edge_meters) MovablePoint.place(self, x=left_edge, y=top_edge) # So the coordinates do not change because of a rounding error self.set_field_top_edge(field_top_edge) self.set_field_left_edge(field_left_edge) def update_input_fields(self): """Updates the input fields, so they reflect where the component is on the screen""" left_edge = pixels_to_meters(self.left_edge) top_edge = pixels_to_meters(self.top_edge) left_edge, top_edge = get_hub_centric_coordinates(left_edge, top_edge) self.set_field_left_edge(truncate(left_edge, INPUT_FIELD_DECIMAL_ACCURACY)) self.set_field_top_edge(truncate(top_edge, INPUT_FIELD_DECIMAL_ACCURACY)) # The reason these methods are needed is because the input field's sometimes have false data def get_left_edge(self): return self.left_edge def get_top_edge(self): return self.top_edge def get_field_left_edge(self): return float(self.left_edge_field.get_text()) def get_field_top_edge(self): return float(self.top_edge_field.get_text()) def set_field_left_edge(self, value, want_rounding=False): if want_rounding: value = truncate(value, INPUT_FIELD_DECIMAL_ACCURACY) self.left_edge_field.set_text(value) def set_field_top_edge(self, value, want_rounding=False): if want_rounding: value = truncate(value, INPUT_FIELD_DECIMAL_ACCURACY) self.top_edge_field.set_text(value) def set_order_position(self, order_position): """Sets the position of the point (point #1, point #2, etc.)""" self.configure(text=order_position) self.order_position_field.set_text(order_position) self.order_position = order_position def destroy(self): """Overrides tkinter's method: removes the button and all the components of the button from the screen""" for field in self.user_modifiable_fields: field.destroy() super().destroy() def get_order_position(self): """ Returns: int: the position of the point (point #1, point #2, etc.)""" return self.order_position def set_position_field_text(self, value): self.order_position_field.configure(text=value) def get_position_field_text(self): return self.order_position_field.get_text() def position_field_is_selected(self): return self.order_position_field.is_selected def get_input_fields(self): """ Returns: InputField: all the input fields that this point has""" return list(filter(lambda item: isinstance(item, InputField) and item.is_editable, self.user_modifiable_fields)) def get_user_modifiable_field(self): """ Returns: list[object]: all the fields the user can modify""" return self.user_modifiable_fields def set_input_fields_command(self, command): """Makes all the input fields call the function 'command' when they are clicked""" for input_field in self.get_input_fields(): input_field.set_command(command) def update_input_fields_belongs_to(self): """So the Main Screen can know what the input field's belong to (a PathModifyingPoint for example)""" for input_field in self.get_input_fields(): input_field.set_belongs_to(self) def select(self): """Makes the point change to the selected color, so the user knows the point is selected""" self.configure(bg=self.selected_color) super().place(x=self.left_edge, y=self.top_edge, width=int(self.base_length * 1.5), height=int(self.base_height * 1.5)) def unselect(self): """Makes the point go back to the base color, so the user knows the point is not selected""" self.configure(bg=self.base_color) super().place(x=self.left_edge, y=self.top_edge, width=int(self.base_length), height=int(self.base_height)) def __str__(self): """FOR DEBUGGING""" return str(self.get_field_top_edge())
Ancestors
- tkinter.Button
- tkinter.Widget
- tkinter.BaseWidget
- tkinter.Misc
- tkinter.Pack
- tkinter.Place
- tkinter.Grid
Class variables
var base_color
var base_height
var base_length
var base_modifiable_fields
var click_function
var color
var is_needed
var left_edge
var left_edge_field
var left_edge_meters
var order_position
var order_position_field
var selected_color
var top_edge
var top_edge_field
var top_edge_meters
var user_modifiable_fields
var user_modifiable_fields_grid
Methods
def default_update_coordinates(self)
-
Moves the component to where the input fields are saying it should be
Expand source code
def default_update_coordinates(self): """Moves the component to where the input fields are saying it should be""" field_top_edge = self.get_field_top_edge() field_left_edge = self.get_field_left_edge() left_edge_meters = self.get_field_left_edge() top_edge_meters = self.get_field_top_edge() top_edge_meters *= -1 left_edge_meters += important_variables.CENTER_OF_FIELD_HORIZONTAL_OFFSET top_edge_meters += CENTER_OF_FIELD_VERTICAL_OFFSET left_edge = meters_to_pixels(left_edge_meters) top_edge = meters_to_pixels(top_edge_meters) MovablePoint.place(self, x=left_edge, y=top_edge) # So the coordinates do not change because of a rounding error self.set_field_top_edge(field_top_edge) self.set_field_left_edge(field_left_edge)
def destroy(self)
-
Overrides tkinter's method: removes the button and all the components of the button from the screen
Expand source code
def destroy(self): """Overrides tkinter's method: removes the button and all the components of the button from the screen""" for field in self.user_modifiable_fields: field.destroy() super().destroy()
def get_field_left_edge(self)
-
Expand source code
def get_field_left_edge(self): return float(self.left_edge_field.get_text())
def get_field_top_edge(self)
-
Expand source code
def get_field_top_edge(self): return float(self.top_edge_field.get_text())
def get_input_fields(self)
-
Returns
InputField
- all the input fields that this point has
Expand source code
def get_input_fields(self): """ Returns: InputField: all the input fields that this point has""" return list(filter(lambda item: isinstance(item, InputField) and item.is_editable, self.user_modifiable_fields))
def get_left_edge(self)
-
Expand source code
def get_left_edge(self): return self.left_edge
def get_order_position(self)
-
Returns
int
- the position of the point (point #1, point #2, etc.)
Expand source code
def get_order_position(self): """ Returns: int: the position of the point (point #1, point #2, etc.)""" return self.order_position
def get_position_field_text(self)
-
Expand source code
def get_position_field_text(self): return self.order_position_field.get_text()
def get_top_edge(self)
-
Expand source code
def get_top_edge(self): return self.top_edge
def get_user_modifiable_field(self)
-
Returns
list[object]
- all the fields the user can modify
Expand source code
def get_user_modifiable_field(self): """ Returns: list[object]: all the fields the user can modify""" return self.user_modifiable_fields
def place(self, want_to_update_input_fields=False, **kwargs)
-
Places the object at that location (x, y, width, height)
Expand source code
def place(self, want_to_update_input_fields=False, **kwargs): """Places the object at that location (x, y, width, height)""" self.left_edge = kwargs.get("x") self.top_edge = kwargs.get("y") if want_to_update_input_fields: self.update_input_fields() kwargs["x"] = int(self.left_edge) kwargs["y"] = int(self.top_edge) super().place(kwargs)
def point_user_alterable_fields(self)
-
Returns
GridItems
- the grid containing all the user modifiable fields
Expand source code
def point_user_alterable_fields(self): """ Returns: GridItems: the grid containing all the user modifiable fields""" return self.user_modifiable_fields_grid
def position_field_is_selected(self)
-
Expand source code
def position_field_is_selected(self): return self.order_position_field.is_selected
def select(self)
-
Makes the point change to the selected color, so the user knows the point is selected
Expand source code
def select(self): """Makes the point change to the selected color, so the user knows the point is selected""" self.configure(bg=self.selected_color) super().place(x=self.left_edge, y=self.top_edge, width=int(self.base_length * 1.5), height=int(self.base_height * 1.5))
def set_field_left_edge(self, value, want_rounding=False)
-
Expand source code
def set_field_left_edge(self, value, want_rounding=False): if want_rounding: value = truncate(value, INPUT_FIELD_DECIMAL_ACCURACY) self.left_edge_field.set_text(value)
def set_field_top_edge(self, value, want_rounding=False)
-
Expand source code
def set_field_top_edge(self, value, want_rounding=False): if want_rounding: value = truncate(value, INPUT_FIELD_DECIMAL_ACCURACY) self.top_edge_field.set_text(value)
def set_input_fields_command(self, command)
-
Makes all the input fields call the function 'command' when they are clicked
Expand source code
def set_input_fields_command(self, command): """Makes all the input fields call the function 'command' when they are clicked""" for input_field in self.get_input_fields(): input_field.set_command(command)
def set_order_position(self, order_position)
-
Sets the position of the point (point #1, point #2, etc.)
Expand source code
def set_order_position(self, order_position): """Sets the position of the point (point #1, point #2, etc.)""" self.configure(text=order_position) self.order_position_field.set_text(order_position) self.order_position = order_position
def set_position_field_text(self, value)
-
Expand source code
def set_position_field_text(self, value): self.order_position_field.configure(text=value)
def unselect(self)
-
Makes the point go back to the base color, so the user knows the point is not selected
Expand source code
def unselect(self): """Makes the point go back to the base color, so the user knows the point is not selected""" self.configure(bg=self.base_color) super().place(x=self.left_edge, y=self.top_edge, width=int(self.base_length), height=int(self.base_height))
def update_input_fields(self)
-
Updates the input fields, so they reflect where the component is on the screen
Expand source code
def update_input_fields(self): """Updates the input fields, so they reflect where the component is on the screen""" left_edge = pixels_to_meters(self.left_edge) top_edge = pixels_to_meters(self.top_edge) left_edge, top_edge = get_hub_centric_coordinates(left_edge, top_edge) self.set_field_left_edge(truncate(left_edge, INPUT_FIELD_DECIMAL_ACCURACY)) self.set_field_top_edge(truncate(top_edge, INPUT_FIELD_DECIMAL_ACCURACY))
def update_input_fields_belongs_to(self)
-
So the Main Screen can know what the input field's belong to (a PathModifyingPoint for example)
Expand source code
def update_input_fields_belongs_to(self): """So the Main Screen can know what the input field's belong to (a PathModifyingPoint for example)""" for input_field in self.get_input_fields(): input_field.set_belongs_to(self)