Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added menubar and buttons to the GUI #12

Merged
merged 13 commits into from
Dec 3, 2024
Merged

Conversation

julius-kress
Copy link
Contributor

Summary

This adds a menu bar to the GUI, as well as checkboxes for selecting which datapoints to use for the fitting of the graph and the calculation of tau.
It also replaces the previous UI mockup.


PR checklist

  • I have written tests that fail without my changes. Or I did not add them on purpose.
  • I have included instructions on how to test this, assuming they are not already apparent from the linked issue.

How to test

There are no end-to-end tests for the UI yet, therefore you can only check the GUI manually.
You can check if it is working properly by making sure it starts without errors.
All buttons should be able to be pressed without errors.
Buttons where the backend functionality is not yet implemented will at least give an output to the developer terminal.

Closes/Fixes/Related to

@julius-kress julius-kress linked an issue Nov 29, 2024 that may be closed by this pull request
4 tasks
@julius-kress julius-kress changed the title Gui/feature/add buttons Added menubar and buttons to the GUI Nov 29, 2024
@julius-kress julius-kress added the GUI Related to the "gui" module label Nov 29, 2024
@Benedikt-Brunner Benedikt-Brunner self-requested a review November 30, 2024 09:29
Comment on lines 6 to 8
:param coordinates: Tuple of the coordinates.
:param is_checked: Boolean value if the checkbox is checked.
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems redundant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rephrased the comment.

@@ -0,0 +1,24 @@
class CheckboxDataPoint:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest moving this class to a model directory, as it is purely a data representation, this helps cleanly segregate your code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 9 to 14
if not isinstance(coordinates, tuple) or len(coordinates) != 2:
raise ValueError("coordinates must be a tuple of two float values")
if not all(isinstance(coord, float) for coord in coordinates):
raise TypeError("all coordinates must be floats.")
if not isinstance(is_checked, bool):
raise TypeError("is_checked must be a bool.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class should only ever be constructed from internal data, therefore all of these should be caught by our static analysis.

We should probably discuss if we want to perform this kind of data validation outside of the modules performing IO

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that validation does not have to happen here.

Comment on lines 20 to 23
"""
Toggles the boolean value
:return: None
"""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general i would like to avoid trivial comments, due to our extensive type hints and naming conventions these should not be necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rephrased the comment.

self.coordinates = coordinates
self.is_checked = is_checked

def toggle_checkbox(self) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class is not dependent on being toggled by a checkbox, it only encapsulates a coordinate that can be toggled, please consider adjusting the naming within this class to remove the semantic dependency on a checkbox

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, i renamed the method.

class GUIApp(customtkinter.CTk):
def __init__(self) -> None:
"""
Constructor for the GUIApp, initializes the GUI.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to emphasize, that this is the logical entry point into the entire GUI

Copy link
Contributor Author

@julius-kress julius-kress Dec 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, added it.

self._init_graph()

# Initialize Checkboxes with datapoints
self._init_datapoint_checkboxes()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your intuition to move these steps into a method is great, however this keeps them in the same file making it much harder to review and edit the code later (especially as we keep adding functionality).

Please move all _init_x methods into separate classes named x and the create and mount them here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this on purpose because I didn't want to over-modularize the code.
If for example the menubar is a separate class, one could argue to also refactor the buttons within the menubar (like File, View, ...) into separate classes and also the options within these buttons.
Then you end up with a lot of classes which are all initialized and used once in the same spot.

But I also see your point, especially for the graph.
What is your opinion on splitting up the GUI only into the classes MenuBar, Graph, Informationfield and Checkboxfield (names more or less like that)?
I would refactor the menubar and checkboxes which this PR/Issue is about and leave the graph and info-field for a separate Issue/PR.

Comment on lines 457 to 459
:param value: The value.
:param window: The window.
:return: The canvas.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted above this comment seems trivial

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs to the graph mockup and shouldn't be part of this PR, as it is gonna be replaced anyways in on of the next issues.

Comment on lines 461 to 478
# the figure that will contain the plot
fig = Figure(figsize=(3, 2), dpi=100, facecolor="white", edgecolor="black")

# list of squares
y = [(i - 50) ** value for i in range(101)]

# adding the subplot
plot1 = fig.add_subplot(111)

# plotting the graph
plot1.plot(y)

# creating the Tkinter canvas
# containing the Matplotlib figure
canvas = FigureCanvasTkAgg(fig, master=window)
canvas.draw()

return canvas.get_tk_widget()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will leave these comments to you, they don't seem terribly trivial but we don't really need all of them, do as you see fit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, this is some leftover code from the graph mockup and will be replaced soon.

@@ -0,0 +1,478 @@
from typing import List, Tuple
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The review of this file wasn't 100% thorough, as there is some higher level work to do moving the Widgets into their own classes. After that is done i will review each one more extensively.

@Benedikt-Brunner
Copy link
Collaborator

I forgot to write it in the final review comment, but the GUI looks really nice, good job!
I think after we make the code a bit more modular this will be really great 👍

Copy link
Collaborator

@Benedikt-Brunner Benedikt-Brunner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed some more things, primarily that you did more work than the Issue describes and we might want to attach that to the other Issue for tracking (very cool, that it's already done however 😅)

Comment on lines 78 to 81
self._init_control_area()

# Initialize information area
self._init_information_area()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Area is a really general term, as is information. We might consider renaming this to control_panel and log_list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like these suggestions and noted them. But I think this should be part of separate issues.

Comment on lines 78 to 81
self._init_control_area()

# Initialize information area
self._init_information_area()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an open draft that i thought was for adding this, you might want to split this out into a separate PR and attach that to the other Issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR only adds the buttons like described in the related issue. However I had to move/replace the previous mockup in some places.
But logically the graph, the control panel and the log list are not implemented yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created the issues #18 , #19 , #20 for that.

Copy link
Collaborator

@Benedikt-Brunner Benedikt-Brunner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muy bueno, there were a few comments where i would have adjusted the wording, but let's just make an issue for reviewing all comments across the repository and push that towards the end of the project. For now it's much more important to get this huge chunk of code into the repo and take that momentum into the next iteration. 👍

image

Comment on lines +74 to +80
self.menu_bar = MenuBar(self, menu_bar_callbacks)

# Initialize the graph
self.graph = Graph(self)

# Initialize the checkbox panel
self.checkbox_panel = CheckboxPanel(self)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply lovely

Comment on lines +4 to +5
if TYPE_CHECKING:
from napytau.gui.app import App # Import only for the type checking.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Props for going above and beyond for static analysis 💪

@Benedikt-Brunner Benedikt-Brunner merged commit 1401346 into main Dec 3, 2024
3 checks passed
@Benedikt-Brunner Benedikt-Brunner deleted the gui/feature/add-buttons branch December 3, 2024 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GUI Related to the "gui" module
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Create dummy buttons
3 participants