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
Refactor setsquare to use MVC pattern #4211
Conversation
Thanks for the great work!
To avoid issues like this, some overlays and tools will have to be owned, not by the PageController, but by the XournalController (currently a mix of XournalView and widget/XournalWidget). The SetSquare is one of those, as are selections for instance. As far as the SetSquare is concerned, I think none of its related classes should be owned by a PageSomething class, and the SetSquare classes should not refer to any specific page (there are bugs on the current master branch if you try to drag the setsquare to a different page and use it there). |
adfc317
to
3015ed5
Compare
Thanks for the input.
I think the setsquare must always refer to a specific page. What should happen otherwise, if you change the page layout (e.g. change from a 2-row setup to a 3-row setup), if the position of the setsquare is not relative to a specific page? Currently when you activate the setsquare, it is activated on a specific page and should only be used there. If you need it on a different page, you should deactivate the setsquare and activate it on the other page. |
I managed to fix the first rendering bug (where the setsquare was invisible until it was manipulated). So everything works again, just the setsquare is overpainted on the next page. Thinking about that issue a little more, it seems to be only a question about rendering priority, not about ownership. Maybe overlays could get a rendering priority assigned, so that overlays of lower priority would only get painted after all overlays (of all pages) of higher priority were painted. |
Sure, I will rebase on master. I have progressed more and already implemented the compass. Now I know better what the setsquare code and its integration in the code base should look like. It will take some time to split everything into sensible commits and PR's. |
6db469d
to
bb51258
Compare
The rebasing is finished. If you could take a look that would be great. I have updated the description on the top to help through the most important commits. |
Currently there are regular pointers
in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Below are a couple of details I noticed while skimming through the code. I have not look at every line of code.
I do have a more important structural remark: I feel like the very existence of gui/inputdevices/GeometryToolHandler (and derived classes) is problematic.
The content of gui/inputdevices/ should be an abstraction layer and no tool implementation should ever end up in this directory.
Of course, you created those classes because you need them: the input system is inadequate and does not handle multitouch as we'd need to avoid tool-specific code.
I'm not familiar enough with the input system to come up with a better structured solution at this point. I need to think.
(Also, we have to keep in mind that GTK4 sees a lot of changes in the input mechnisms, so porting to GTK4 will someday require extensive work on the input system.)
I agree that those files look misplaced. Maybe @LittleHuba has an opinion about how to deal with it.
We should probably get acquainted with the input mechanism in GTK4 as soon as possible and try to figure out what changes will be required when porting. |
Historically the input system was only a fix to get rid of the old c-style input handling. In general I think it is simply impossible to get rid of all tool specific code in the input handling. Thus, for me the goal would be to at least separate the unspecific handling very strictly from the tool specific handling to get something like a layered system. How that would be possible, I honestly don't know yet. |
8e2ecbf
to
7d48483
Compare
Rebased and fixed merge conflict. |
/azp run create-installers |
Azure Pipelines successfully started running 1 pipeline(s). |
07cc1a9
to
bf58c4c
Compare
Cleaned up the commit history a bit (with no functional changes) and rebased on current master. |
This is a continuation of #3962 and is based on #4137, #4158 and #4159 from @bhennion.This PR refactors the setsquare.
Currently it contains adding a compass, but that will later be moved into another PR.Previously it contained a compass, but that was moved into PR #4443.
I tried to follow the MVC pattern (push variant) explained by @LittleHuba in #3962 (comment).
Only the last two commits are relevant.I will explain the most relevant commits:
In 6efc15a the MVC pattern is applied:
The class
Setsquare
is the model.The class
SetsquareView
is the view.The class
SetsquareController
is the controller.The class
SetsquareInputHandler
is somewhere between a view and a controller.The model has a
viewPool
and ahandlerPool
for pushing updates to theSetsquareView
(s) andSetsquareInputHandler
(s).It stores the data for the setsquare and the stroke (near the longest side of the setsquare or from a point close to a shorter side of the setsquare to the midpoint of the longest side) and has getters and setters.
The view only uses the model for querying the
viewPool
. It doesn't update the model and contains only drawing methods except of the methods to update itself when pushed from the model.The input handler just handles input and uses the controller to manipulate the model. It also updates itself when pushed from the model.
The controller manipulates the model (moves, rotates and scales the setsquare, creates and updates strokes) and contains more methods, which didn't fit in one of the other classes.
For pushing updates to the view and input handler, I use the
xoj::util::Listener
class; for rendering the setsquare I use theOverlayBase
andToolView
classes, all by @bhennion .There
are still two issuesis still one issue with the rendering:1) When activating the setsquare, it is not rendered immediately. It is only rendered after it has been moved/scaled or rotated. I'm not sure why that happens. I tried to notify the setsquare after constructing instances of all classes (inControl.cpp
), but that crashes.2)Since the rendering uses an overlay of one of the page views and the pages are drawn one after the other, when moving the setsquare towards the next page, the fraction that lands on the next page appears to be cut, as if the setsquare was gliding under the next page. It's not like that when moving the setsquare to the page before.In order to prepare for other geometry tools (like a compass or a ruler) to be added, in 714e479 the Setsquare classes are derived from more generic GeometryTool classes. Those classes basically contain the functionality of the Setsquare that all geometry tools will most likely share. This makes it easier to implement new geometry tools.
Setsquare
is derived fromGeometryTool
SetsquareView
is derived fromGeometryToolView
SetsquareController
is derived fromGeometryToolController
SetsquareInputHandler
is derived fromGeometryToolHandler
This strategy is demonstrated in
commit bb51258PR #4443 where the Compass is added.Although that commit won't be part of this PR, it is included so that the strategy can be checked to work.Any feedback is welcome. As I had no previous exposure to the MVC pattern, I find it quite tough to find the proper way for this refactoring.
Only the two last commits are relevant:ff90582 is the combination of the commits in #3962 rebased on #4159. The setsquare is functionally equivalent to the version in master.
The real work is in adfc317
Edit: Updated description, described derivation from GeometryTool classes (Oct 15)
Edit: Updated description after moving the compass into another PR.