As part of my bachelor's degree, I'm trying to develop something that looks like a painting program. This means that I have a set of tools, be it selection, drawing, highlighting, and so on.
I will have a canvas showing my current model, based on a set of rectangles / spheres / polygons that I have already drawn and created.
Some tools require the view to react differently depending on the tools. Approximate examples:
I have a tool "New Line". The view now shows the points you can connect to when you hover over them.
I have a tool "Selection". When I fly over an element, its color changes entirely.
I have a tool "New Element". When I move the mouse, a shadow of the element follows my cursor until I press the left mouse button.
Now, here's where I'm a little stuck:
All of these tools require a very different behavior from the view, and the view must also be dynamic based on the calculated properties. I had some ideas on how I could design my system, but I would prefer to be pushed in one direction before making a huge mistake. Here are my questions and thoughts:
Q: First of all, where can I even put this interactive code? I can not do it in XML, because it requires calculations, but placing it in the ViewModel is also not correct, because ViewModel is not supposed to know the view. So, do I put it in the Code of Sight itself? It also seems a little strange.
Let's go now to my architectural ideas:
Idea 1: I could create a new View + Viewmodel for each tool. When a new tool is selected, the view and view template are simply exchanged in a frame and all behavior is encapsulated in the new view + view template. However, it seems that not only the View and the ViewModel are closely related, but that it also feels like a lot of boilerplate code.
Idea 2: Each tool itself has a "Command" class based on an ICommand interface that requires a reference to the view as well as all possible options for user interaction. Then, the ViewModel delegates the UserInput to the current command, which can then manipulate the given ViewInstance to display the items it wishes. However, this seems very rigid, as if I only delegate the problem of Idea 1 elsewhere and incapable of future growth. Whenever I want to add a new way for a user to interact, I should adjust the interface and perhaps all the underlying commands if I did not provide default implementation.
None of these really satisfies me and I feel that I miss a crucial step for this part of the architecture. I would gladly appreciate any pointer. Thank you for your time and reading!