Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 65 additions & 91 deletions component_sketch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import os



from dataCDLT import (
HORIZONTAL,
RIGHT,
Expand Down Expand Up @@ -72,7 +71,6 @@ def __init__(self, canvas) -> None:
self.id_origins = {"xyOrigin": (0, 0)}
self.battery_wire_drag_data: dict[str, Any] = {}


def circuit(self, x_distance=0, y_distance=0, scale=1, width=-1, direction=VERTICAL, **kwargs):
"""
Generates a circuit layout on the canvas based on the provided parameters and model.
Expand Down Expand Up @@ -345,7 +343,7 @@ def on_wire_body_leave(self, *_):
"""
Event handler for when the mouse leaves the wire body.
"""
if not self.drag_selector and not self.wire_drag_data["creating_wire"]:
if not self.drag_selector and not self.wire_drag_data["creating_wire"] and not self.delete_mode_active:
self.canvas.config(cursor="arrow")

def on_wire_body_click(self, event, wire_id) -> None:
Expand Down Expand Up @@ -2666,8 +2664,6 @@ def draw_pin_io(self, x_distance, y_distance, scale=1, width=-1, direction=HORIZ
matrix[f"{coord[0][0]},{coord[0][1]}"]["state"] = USED

return x_distance, y_distance



def clear_board(self):
"""Clear the board of all drawn components."""
Expand All @@ -2681,13 +2677,20 @@ def clear_board(self):
self.current_dict_circuit.clear()
# TODO Khalid update the Circuit instance




def draw_battery(self, x_distance, y_distance, scale=1, width=-1, direction='HORIZONTAL', pos_wire_end=None, neg_wire_end=None, **kwargs):
def draw_battery(
self,
x_distance,
y_distance,
scale=1,
width=-1,
direction="HORIZONTAL",
pos_wire_end=None,
neg_wire_end=None,
**kwargs,
):
"""
Draws a battery image at the given coordinates with two hanging wires on the left side.

Parameters:
- x_distance (int): The x-coordinate where the battery will be drawn.
- y_distance (int): The y-coordinate where the battery will be drawn.
Expand All @@ -2697,11 +2700,11 @@ def draw_battery(self, x_distance, y_distance, scale=1, width=-1, direction='HOR
- pos_wire_end (tuple): Coordinates where the positive wire should end.
- neg_wire_end (tuple): Coordinates where the negative wire should end.
- kwargs: Additional keyword arguments.

Returns:
- Tuple of (x_distance, y_distance)
"""
battery_id = '_battery'
battery_id = "_battery"

# Check if battery already exists
if battery_id in self.current_dict_circuit:
Expand Down Expand Up @@ -2748,35 +2751,28 @@ def draw_battery(self, x_distance, y_distance, scale=1, width=-1, direction='HOR
return x_distance, y_distance

battery_obj = self.canvas.create_image(
x_distance - 10,
y_distance,
anchor='nw',
image=battery_photo,
tags=(battery_id,)
x_distance - 10, y_distance, anchor="nw", image=battery_photo, tags=(battery_id,)
)

if not hasattr(self, 'image_references'):
if not hasattr(self, "image_references"):
self.image_references = []
self.image_references.append(battery_photo)

neg_wire_offset_x = 0 # Left edge
neg_wire_offset_y = new_height * 0.2 # 20% from the top

pos_wire_offset_x = 0 # Left edge
pos_wire_offset_y = new_height * 0.8
pos_wire_offset_y = new_height * 0.8

neg_wire_start_x = x_distance + neg_wire_offset_x
neg_wire_start_y = y_distance + neg_wire_offset_y

pos_wire_start_x = x_distance + pos_wire_offset_x
pos_wire_start_y = y_distance + pos_wire_offset_y

self.current_dict_circuit[battery_id] = {
'id': battery_id,
'tags': [battery_id]
}
self.current_dict_circuit[battery_id] = {"id": battery_id, "tags": [battery_id]}

neg_wire_id = '_battery_neg_wire'
neg_wire_id = "_battery_neg_wire"
if neg_wire_end:
neg_wire_end_x, neg_wire_end_y = neg_wire_end
else:
Expand All @@ -2790,10 +2786,10 @@ def draw_battery(self, x_distance, y_distance, scale=1, width=-1, direction='HOR
end_x=neg_wire_end_x + 3,
end_y=neg_wire_end_y + 3,
color=(0, 0, 0),
terminal_type='neg'
terminal_type="neg",
)

pos_wire_id = '_battery_pos_wire'
pos_wire_id = "_battery_pos_wire"
if pos_wire_end:
pos_wire_end_x, pos_wire_end_y = pos_wire_end
else:
Expand All @@ -2807,13 +2803,13 @@ def draw_battery(self, x_distance, y_distance, scale=1, width=-1, direction='HOR
end_x=pos_wire_end_x + 3,
end_y=pos_wire_end_y + 3,
color=(255, 0, 0),
terminal_type='pos'
terminal_type="pos",
)

self.canvas.tag_raise(battery_id)

self.current_dict_circuit[battery_id]['tags'].extend(
self.current_dict_circuit[pos_wire_id]['tags'] + self.current_dict_circuit[neg_wire_id]['tags']
self.current_dict_circuit[battery_id]["tags"].extend(
self.current_dict_circuit[pos_wire_id]["tags"] + self.current_dict_circuit[neg_wire_id]["tags"]
)

return x_distance, y_distance
Expand All @@ -2833,23 +2829,11 @@ def draw_battery_wire(self, wire_id, start_x, start_y, end_x, end_y, color, term

# shadow line
self.canvas.create_line(
start_x,
start_y,
end_x,
end_y,
fill=contour,
width=8 * thickness,
tags=(wire_id, wire_body_shadow_tag)
start_x, start_y, end_x, end_y, fill=contour, width=8 * thickness, tags=(wire_id, wire_body_shadow_tag)
)
# main line
self.canvas.create_line(
start_x,
start_y,
end_x,
end_y,
fill=encre,
width=4 * thickness,
tags=(wire_id, wire_body_tag)
start_x, start_y, end_x, end_y, fill=encre, width=4 * thickness, tags=(wire_id, wire_body_tag)
)

radius = 2 * self.scale_factor
Expand All @@ -2858,37 +2842,37 @@ def draw_battery_wire(self, wire_id, start_x, start_y, end_x, end_y, color, term
end_y - radius,
end_x + radius,
end_y + radius,
fill='green' if terminal_type == 'pos' else 'black',
outline='',
tags=(endpoint_tag,)
fill="green" if terminal_type == "pos" else "black",
outline="",
tags=(endpoint_tag,),
)

self.current_dict_circuit[wire_id] = {
'id': wire_id,
'tags': [wire_id, wire_body_tag, wire_body_shadow_tag, endpoint_tag],
'start': (start_x, start_y),
'end': (end_x, end_y),
'color': color,
'terminal_type': terminal_type,
'endpoint_tag': endpoint_tag,
"id": wire_id,
"tags": [wire_id, wire_body_tag, wire_body_shadow_tag, endpoint_tag],
"start": (start_x, start_y),
"end": (end_x, end_y),
"color": color,
"terminal_type": terminal_type,
"endpoint_tag": endpoint_tag,
}

self.canvas.tag_bind(
endpoint_tag,
"<Button-1>",
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_click(event, wire_id)
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_click(event, wire_id),
)
self.canvas.tag_bind(
endpoint_tag,
"<B1-Motion>",
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_drag(event, wire_id)
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_drag(event, wire_id),
)
self.canvas.tag_bind(
endpoint_tag,
"<ButtonRelease-1>",
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_release(event, wire_id)
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_release(event, wire_id),
)

def create_battery_wire_endpoint(self, x, y, wire_id, terminal_type):
"""
Creates an interactive endpoint for a battery wire.
Expand All @@ -2901,28 +2885,28 @@ def create_battery_wire_endpoint(self, x, y, wire_id, terminal_type):
y - radius,
x + radius,
y + radius,
fill='green' if terminal_type == 'pos' else 'black',
outline='',
tags=(endpoint_tag,)
fill="green" if terminal_type == "pos" else "black",
outline="",
tags=(endpoint_tag,),
)

self.canvas.tag_bind(
endpoint_tag,
"<Button-1>",
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_click(event, wire_id)
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_click(event, wire_id),
)
self.canvas.tag_bind(
endpoint_tag,
"<B1-Motion>",
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_drag(event, wire_id)
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_drag(event, wire_id),
)
self.canvas.tag_bind(
endpoint_tag,
"<ButtonRelease-1>",
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_release(event, wire_id)
lambda event, wire_id=wire_id: self.on_battery_wire_endpoint_release(event, wire_id),
)

self.current_dict_circuit[wire_id]['endpoint_tag'] = endpoint_tag
self.current_dict_circuit[wire_id]["endpoint_tag"] = endpoint_tag

def on_battery_wire_endpoint_click(self, event, wire_id):
"""
Expand All @@ -2932,39 +2916,33 @@ def on_battery_wire_endpoint_click(self, event, wire_id):
x, y = event.x, event.y
_, nearest_point_coord = self.find_nearest_grid_point(x, y)
old_col, old_line = nearest_point_coord
self.matrix[f'{old_col},{old_line}']['state'] = FREE
self.matrix[f"{old_col},{old_line}"]["state"] = FREE
self.battery_wire_drag_data = {
'wire_id': wire_id,
"wire_id": wire_id,
}

def on_battery_wire_endpoint_drag(self, event, wire_id):
"""
Handler for dragging a battery wire endpoint.
Updates the wire's end position as it's being dragged.
"""
if self.battery_wire_drag_data['wire_id'] != wire_id:
if self.battery_wire_drag_data["wire_id"] != wire_id:
return

wire_data = self.current_dict_circuit[wire_id]
start_x, start_y = wire_data['start']
start_x, start_y = wire_data["start"]

wire_body_tag = f"{wire_id}_body"
wire_body_shadow_tag = f"{wire_id}_body_shadow"

self.canvas.coords(wire_body_shadow_tag, start_x, start_y, event.x, event.y)
self.canvas.coords(wire_body_tag, start_x, start_y, event.x, event.y)

endpoint_tag = wire_data['endpoint_tag']
endpoint_tag = wire_data["endpoint_tag"]
radius = 5 * self.scale_factor
self.canvas.coords(
endpoint_tag,
event.x - radius,
event.y - radius,
event.x + radius,
event.y + radius
)
self.canvas.coords(endpoint_tag, event.x - radius, event.y - radius, event.x + radius, event.y + radius)

wire_data['end'] = (event.x, event.y)
wire_data["end"] = (event.x, event.y)

def on_battery_wire_endpoint_release(self, event, wire_id):
"""
Expand All @@ -2979,7 +2957,7 @@ def on_battery_wire_endpoint_release(self, event, wire_id):
return

wire_data = self.current_dict_circuit[wire_id]
start_x, start_y = wire_data['start']
start_x, start_y = wire_data["start"]
new_end_x, new_end_y = nearest_point

wire_body_tag = f"{wire_id}_body"
Expand All @@ -2988,20 +2966,16 @@ def on_battery_wire_endpoint_release(self, event, wire_id):
self.canvas.coords(wire_body_shadow_tag, start_x, start_y, new_end_x + 3, new_end_y + 3)
self.canvas.coords(wire_body_tag, start_x, start_y, new_end_x + 3, new_end_y + 3)

endpoint_tag = wire_data['endpoint_tag']
endpoint_tag = wire_data["endpoint_tag"]
radius = 2 * self.scale_factor
self.canvas.coords(
endpoint_tag,
new_end_x - radius + 3,
new_end_y - radius + 3,
new_end_x + radius + 3,
new_end_y + radius + 3
endpoint_tag, new_end_x - radius + 3, new_end_y - radius + 3, new_end_x + radius + 3, new_end_y + radius + 3
)

wire_data['end'] = (new_end_x, new_end_y)
wire_data["end"] = (new_end_x, new_end_y)

col, line = nearest_point_coord
self.matrix[f'{col},{line}']['state'] = USED
self.matrix[f"{col},{line}"]["state"] = USED

self.battery_wire_drag_data = {}

Expand All @@ -3010,14 +2984,14 @@ def get_power_line_last_pins(self):
Returns a list of allowed positions (x, y, col, line) for the battery wires.
"""
allowed_positions = []
last_col = 61
last_col = 61
power_lines = [1, 2, 13, 14, 15, 16, 27, 28]

for line in power_lines:
col = last_col
key = f"{col},{line}"
if key in self.matrix:
x, y = self.matrix[key]['xy']
x, y = self.matrix[key]["xy"]
x += self.id_origins["xyOrigin"][0]
y += self.id_origins["xyOrigin"][1]
allowed_positions.append((x, y, col, line))
Expand All @@ -3028,17 +3002,17 @@ def find_nearest_allowed_grid_point(self, x, y, allowed_positions):
Find the nearest grid point among the allowed positions to the given x, y coordinates.
Skips positions that are already USED.
"""
min_distance = float('inf')
min_distance = float("inf")
nearest_point = (x, y)
nearest_point_coord = None
for grid_x, grid_y, col, line in allowed_positions:
# Check if the hole is FREE
hole_state = self.matrix.get(f'{col},{line}', {}).get('state', None)
hole_state = self.matrix.get(f"{col},{line}", {}).get("state", None)
if hole_state != FREE:
continue
distance = math.hypot(x - grid_x, y - grid_y)
if distance < min_distance:
min_distance = distance
nearest_point = (grid_x, grid_y)
nearest_point_coord = (col, line)
return nearest_point, nearest_point_coord
return nearest_point, nearest_point_coord
Loading