Skip to content

Commit

Permalink
Merge pull request #53 from pyiron/cleanup_sep9
Browse files Browse the repository at this point in the history
Cleanup
  • Loading branch information
liamhuber authored Oct 12, 2022
2 parents 554054c + 39584bb commit 6ddcbf7
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 245 deletions.
4 changes: 2 additions & 2 deletions ryven/ironflow/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__all__ = ['gui', 'flow_canvas', 'canvas_widgets', 'node_interface.py']
__all__ = ['gui', 'flow_canvas', 'canvas_widgets', 'layouts', 'models', 'node_interface']

from .gui import GUI
from ryven.ironflow.gui import GUI
from ryven.NENV import Node, NodeInputBP, NodeOutputBP, dtypes
113 changes: 48 additions & 65 deletions ryven/ironflow/canvas_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

import numpy as np
from IPython.display import display
from .layouts import Layout, NodeLayout, PortLayout, DataPortLayout, ExecPortLayout, ButtonLayout
from ryven.ironflow.layouts import Layout, NodeLayout, PortLayout, DataPortLayout, ExecPortLayout, ButtonLayout
from abc import ABC, abstractmethod
from ryvencore.NodePort import NodeInput, NodeOutput

from typing import TYPE_CHECKING, Optional, Union, List, Callable
from typing import TYPE_CHECKING, Optional, Union
if TYPE_CHECKING:
from .flow_canvas import FlowCanvas
from ryven.ironflow.flow_canvas import FlowCanvas
from ryven.ironflow.gui import GUI
from ipycanvas import Canvas
from ryven.NENV import Node, NodeInputBP, NodeOutputBP
Expand All @@ -21,7 +21,7 @@
from ryvencore.Flow import Flow


__author__ = "Joerg Neugebauer"
__author__ = "Joerg Neugebauer, Liam Huber"
__copyright__ = (
"Copyright 2020, Max-Planck-Institut für Eisenforschung GmbH - "
"Computational Materials Design (CM) Department"
Expand All @@ -42,7 +42,7 @@ def __init__(
self,
x: Number,
y: Number,
parent: Union[FlowCanvas, CanvasWidget],
parent: FlowCanvas | CanvasWidget,
layout: Layout,
selected: bool = False,
title: Optional[str] = None,
Expand All @@ -60,15 +60,12 @@ def __init__(
self._height = self.layout.height

@abstractmethod
def on_click(self, last_selected_object: Optional[CanvasWidget]) -> Optional[CanvasWidget]:
def on_click(self, last_selected_object: Optional[CanvasWidget]) -> CanvasWidget | None:
pass

def on_double_click(self) -> Optional[CanvasWidget]:
def on_double_click(self) -> CanvasWidget | None:
return self

def _init_after_parent_assignment(self):
pass

@property
def width(self) -> int:
return self.layout.width
Expand All @@ -79,11 +76,11 @@ def height(self) -> int:

@property
def x(self) -> Number:
return self.parent.x + self._x # - self.parent.width//2
return self.parent.x + self._x

@property
def y(self) -> Number:
return self.parent.y + self._y # - self.parent.height//2
return self.parent.y + self._y

@property
def canvas(self) -> Canvas:
Expand Down Expand Up @@ -114,8 +111,8 @@ def add_x_y(self, dx_in: Number, dy_in: Number) -> None:
def draw_shape(self) -> None:
self.canvas.fill_style = self.layout.selected_color if self.selected else self.layout.background_color
self.canvas.fill_rect(
self.x, # - (self.width * 0.5),
self.y, # - (self.height * 0.5),
self.x,
self.y,
self.width,
self.height,
)
Expand All @@ -132,11 +129,11 @@ def draw(self) -> None:
o.draw()

def _is_at_xy(self, x_in: Number, y_in: Number) -> bool:
x_coord = self.x # - (self.width * 0.5)
y_coord = self.y # - (self.height * 0.5)
x_coord = self.x
y_coord = self.y
return x_coord < x_in < (x_coord + self.width) and y_coord < y_in < (y_coord + self.height)

def get_element_at_xy(self, x_in: Number, y_in: Number) -> Union[CanvasWidget, None]:
def get_element_at_xy(self, x_in: Number, y_in: Number) -> CanvasWidget | None:
if self.is_here(x_in, y_in):
for o in self.objects_to_draw:
if o.is_here(x_in, y_in):
Expand Down Expand Up @@ -165,7 +162,7 @@ def __init__(
self,
x: Number,
y: Number,
parent: Union[FlowCanvas, CanvasWidget],
parent: FlowCanvas | CanvasWidget,
layout: Layout,
selected: bool = False,
title: Optional[str] = None,
Expand Down Expand Up @@ -222,7 +219,7 @@ def __init__(
self,
x: Number,
y: Number,
parent: Union[FlowCanvas, CanvasWidget],
parent: FlowCanvas | CanvasWidget,
layout: PortLayout,
port: NodePort,
selected: bool = False,
Expand All @@ -245,7 +242,7 @@ def __init__(
self.radius = radius
self.port = port

def on_click(self, last_selected_object: Optional[CanvasWidget]) -> Optional[CanvasWidget]:
def on_click(self, last_selected_object: Optional[CanvasWidget]) -> PortWidget | None:
if last_selected_object == self:
self.deselect()
return None
Expand Down Expand Up @@ -277,7 +274,7 @@ def __init__(
self,
x: Number,
y: Number,
parent: Union[FlowCanvas, CanvasWidget],
parent: FlowCanvas | CanvasWidget,
layout: NodeLayout,
node: Node,
selected: bool = False,
Expand All @@ -303,26 +300,25 @@ def __init__(
'exec': ExecPortLayout()
}

self._title_box_height = 30

n_ports_max = max(len(self.node.inputs), len(self.node.outputs))
n_ports_min = len([p for p in self.node.inputs if p.type_ == "exec"])
n_ports_max = max(len(self.node.inputs), len(self.node.outputs)) + 1 # Includes the expand/collapse button
exec_port_i = np.where([p.type_ == "exec" for p in self.node.inputs])[0]
n_ports_min = exec_port_i[-1] + 1 if len(exec_port_i) > 0 else 1
subwidget_size_and_buffer = 1.33 * 2 * self.port_radius
self._io_height = subwidget_size_and_buffer * n_ports_max
self._exec_height = subwidget_size_and_buffer * n_ports_min
# TODO: Right now we're hard-coding in that all the exec ports (which come with buttons) appear first in input
# This isn't necessarily so, nor checked for anywhere. Do better.
self._expand_collapse_height = subwidget_size_and_buffer
self._title_box_height = self.layout.title_box_height
self._max_body_height = subwidget_size_and_buffer * n_ports_max
self._min_body_height = subwidget_size_and_buffer * n_ports_min
self._expanded_height = self._title_box_height + self._max_body_height
self._collapsed_height = self._title_box_height + self._min_body_height
self._height = self._expanded_height

y_step = (self._io_height + self._expand_collapse_height) / (n_ports_max + 1)
self._port_y_locs = (np.arange(n_ports_max + 1) + 0.5) * y_step + self._title_box_height
y_step = self._max_body_height / n_ports_max
self._subwidget_y_locs = (np.arange(n_ports_max) + 0.5) * y_step + self._title_box_height

self.add_inputs()
self.add_outputs()
self.expand_button = ExpandButtonWidget(
x=0.5 * self.width - self.port_radius,
y=self._port_y_locs[0] - self.port_radius,
y=self._subwidget_y_locs[0] - self.port_radius,
parent=self,
layout=ButtonLayout(),
pressed=True,
Expand All @@ -332,7 +328,7 @@ def __init__(
self.add_widget(self.expand_button)
self.collapse_button = CollapseButtonWidget(
x=0.5 * self.width - self.port_radius,
y=self._port_y_locs[-1] - self.port_radius,
y=self._subwidget_y_locs[-1] - self.port_radius,
parent=self,
layout=ButtonLayout(),
pressed=False,
Expand All @@ -341,7 +337,7 @@ def __init__(
)
self.add_widget(self.collapse_button)

def on_click(self, last_selected_object: Optional[CanvasWidget]) -> Optional[CanvasWidget]:
def on_click(self, last_selected_object: Optional[CanvasWidget]) -> NodeWidget | None:
if last_selected_object == self:
return self
else:
Expand All @@ -357,7 +353,7 @@ def on_click(self, last_selected_object: Optional[CanvasWidget]) -> Optional[Can
self.deselect()
return None

def on_double_click(self) -> Optional[CanvasWidget]:
def on_double_click(self) -> None:
self.delete()
return None

Expand All @@ -373,8 +369,8 @@ def draw_title(self) -> None:
def _add_ports(
self,
radius: Number,
inputs: Optional[List[NodeInputBP]] = None,
outputs: Optional[List[NodeOutputBP]] = None,
inputs: Optional[list[NodeInputBP]] = None,
outputs: Optional[list[NodeOutputBP]] = None,
border: Number = 1.4,
) -> None:
if inputs is not None:
Expand All @@ -393,21 +389,21 @@ def _add_ports(
self.add_widget(
PortWidget(
x=x,
y=self._port_y_locs[i_port],
y=self._subwidget_y_locs[i_port],
parent=self,
layout=self.port_layouts[data_or_exec],
port=port,
hidden_x=x,
hidden_y=self._port_y_locs[0],
hidden_y=self._subwidget_y_locs[0],
radius=radius,
)
)
if data_or_exec == "exec" and inputs is not None:
button_layout = ButtonLayout()
self.add_widget(
ExecButtonWidget(
x=x + 0.3 * button_layout.width,
y=self._port_y_locs[i_port] - 0.5 * button_layout.height,
x=x + radius,
y=self._subwidget_y_locs[i_port] - 0.5 * button_layout.height,
parent=self,
layout=button_layout,
port=port
Expand All @@ -434,37 +430,25 @@ def delete(self) -> None:
def port_widgets(self) -> list[PortWidget]:
return [o for o in self.objects_to_draw if isinstance(o, PortWidget)]

@property
def _expanded_height(self) -> Number:
return self._title_box_height + self._io_height + self._expand_collapse_height

@property
def _collapsed_height(self) -> Number:
return self._title_box_height + max(self._expand_collapse_height, self._exec_height)

def expand_io(self):
self._height = self._expanded_height
for o in self.port_widgets:
o.show()
# self.collapse_button.on_click() # Why doesn't this do the same as the next two lines??
self.collapse_button.on_unpressed()
self.collapse_button.pressed = False
self.collapse_button.unpress()

def collapse_io(self):
self._height = self._collapsed_height
for o in self.port_widgets:
o.hide()
# TODO: The expand and collapse buttons are effectively an XOR toggle...improve this awkward implementation
self.expand_button.on_unpressed()
self.expand_button.pressed = False
self.expand_button.unpress()


class ButtonNodeWidget(NodeWidget):
def __init__(
self,
x: Number,
y: Number,
parent: Union[FlowCanvas, CanvasWidget],
parent: FlowCanvas | CanvasWidget,
layout: NodeLayout,
node: Node,
selected: bool = False,
Expand All @@ -478,7 +462,7 @@ def __init__(
button_layout = ButtonLayout()
self.exec_button = ExecButtonWidget(
x=0.8 * (self.width - button_layout.width),
y=self._port_y_locs[0] - 0.5 * button_layout.height,
y=self._subwidget_y_locs[0] - 0.5 * button_layout.height,
parent=self,
layout=button_layout,
port=self.node.outputs[0],
Expand All @@ -501,7 +485,7 @@ def __init__(
self.title = title
self.pressed = pressed

def on_click(self, last_selected_object: Optional[CanvasWidget]) -> Optional[CanvasWidget]:
def on_click(self, last_selected_object: Optional[CanvasWidget]) -> CanvasWidget | None:
if self.pressed:
self.unpress()
else:
Expand Down Expand Up @@ -550,7 +534,7 @@ def __init__(
parent: DisplayableNodeWidget,
layout: ButtonLayout,
selected: bool = False,
title="PLOT",
title="SHOW",
):
super().__init__(x, y, parent, layout, selected, title=title)

Expand All @@ -572,7 +556,7 @@ def __init__(
self,
x: Number,
y: Number,
parent: Union[FlowCanvas, CanvasWidget],
parent: FlowCanvas | CanvasWidget,
layout: NodeLayout,
node: Node,
selected: bool = False,
Expand Down Expand Up @@ -647,9 +631,8 @@ def __init__(
if size is not None:
layout.width = size
layout.height = size
dpl = DataPortLayout()
layout.background_color = dpl.background_color
layout.pressed_color = dpl.background_color
layout.background_color = parent.node.color
layout.pressed_color = parent.node.color

ButtonWidget.__init__(self, x=x, y=y, parent=parent, layout=layout, selected=selected, title=title,
pressed=pressed)
Expand Down Expand Up @@ -718,7 +701,7 @@ def __init__(
parent=parent,
layout=layout,
selected=selected,
title=port.label_str if port.label_str is not None else title,
title=port.label_str if port.label_str != '' else title,
pressed=pressed
)
self.port = port
Expand Down
Loading

0 comments on commit 6ddcbf7

Please sign in to comment.