PeterBjuhr / frescobaldi

Frescobaldi LilyPond Editor
http://www.frescobaldi.org/
GNU General Public License v2.0
0 stars 0 forks source link

dragging granularity #21

Open uliska opened 10 years ago

uliska commented 10 years ago

Do you know why dragging proceeds in steps of .15 currently? It seems to be independent from the zoom factor.

I don't really see a cause for this, and I'd really prefer to have this with a pixel-precision granularity.

uliska commented 10 years ago

OK, I did some tests, and I'm convinced that the problem is in mousePos() in the line svgPoint = svgPoint.matrixTransform(svg.getScreenCTM().inverse());

One line before event.clientX and Y return one-pixel values after that function we have the ca. 0.15 units "zipper".

Unfortunately I don't really understand what that line or its components do.

uliska commented 10 years ago

The a and d properties of svg.getScreenCTM().inverse() both give 0.1584868483367355

Don't you think that's bringing us on track of the issue?

uliska commented 10 years ago

The f property gives a value that is dependent of the zoom factor. a and d are independent. Well, what I can't check is whether this may be a hardcoded value for my screen resolution. So would you please check if your precision is 0.15 too?

PeterBjuhr commented 10 years ago

Yes, maybe we're getting somewhere now! :-)

The line you're referring to was a solution to the original problems with the dragging I found. It's supposed to fix the conversion between the mm unit in the svg file and the pixel unit in the mouse movement.

uliska commented 10 years ago

I have read what getScreenCTM is supposed to do, but I don't understand what the matrix operations are really about ...

PeterBjuhr commented 10 years ago

So would you please check if your precision is 0.15 too?

Yes, I can confirm that the behavior is exactly as you described it. The object can't be moved less than 0.15 in either the x or y direction, and it's independent of the zoom factor.

PeterBjuhr commented 10 years ago

The f property gives a value that is dependent of the zoom factor. a and d are independent.

If I understand it correctly when we use the translate functionality we only use the coordinates e and f.

uliska commented 10 years ago

Yes, I think too - but from what object? In the getScreenCTM() in mousePos() only a, d, and f have a value at all.

uliska commented 10 years ago

If I understand it correctly when we use the translate functionality we only use the coordinates e and f.

I think we use these coordinates for the object to be translated, and I think we could set arbitrary values there. The problem comes from the conversion of screen pixels to SVG coordinates in said function. There we get that 0.15.. step. This also confirms that the issue isn't related to when we do the two-digit rounding.

I have tried around some more last night and tried to understand the SVG reference entries but I have to admit I'm at a loss here. I have identified the offending line in our source and have now to defer to you - or to asking somewhere, e.g. stackoverflow.

PeterBjuhr commented 10 years ago

Ok, great debugging! I'll see if I can find a way forward.

PeterBjuhr commented 10 years ago

I don't know if we can make good use out of this yet but I've found out one thing!

The viewBox is used for setting the scaling of the document. I got the idea to see what happens if the document is scaled down to a lesser degree. I edited the viewbox values manually (in the SVG file) and got a positive result; I could move as little as 0.06. I guess that you could conclude from this that with an even lesser scaling we could get the result we want.

The problem with this approach is that we need to adjust not only the viewBox but also the width and height to fit everything on the screen.

uliska commented 10 years ago

Hm, I'm not sure where this might lead to. I've read about the viewBox attribute. And indeed changing this will change the scaling of the document. I have the impression that this would also break the relation of svg units to lilypond staff spaces.

But on the other hand I'm surprised about one thing: In theory the current viewBox setting should make the image show only a part of the document, but actually it displays the whole page. So it seems the viewBox is only working as a coordinate transformation system here.

And I don't think it is a viable solution to edit the SVG file itself from Frescobaldi. I think we should somehow find a solution to deal with the given file's information, that is somehow circumvent the issue in the matrix transformation.

uliska commented 10 years ago

Just made another test, and this shows we're still somewhat wrong. Consider the following debug output of a (more or less) horizontal dragging operation:

X: 165 | Y: 84
X: 24.835222244262695 | Y: 12.647253036499023
New mouse position:
X: 165 | Y: 84
X: 24.835222244262695 | Y: 12.647253036499023
New mouse position:
X: 165 | Y: 84
X: 24.835222244262695 | Y: 12.647253036499023
New mouse position:
X: 164 | Y: 84
X: 24.68465805053711 | Y: 12.647253036499023
New mouse position:
X: 164 | Y: 84
X: 24.68465805053711 | Y: 12.647253036499023
New mouse position:
X: 164 | Y: 84
X: 24.68465805053711 | Y: 12.647253036499023
New mouse position:
X: 164 | Y: 84
X: 24.68465805053711 | Y: 12.647253036499023
New mouse position:
X: 163 | Y: 84
X: 24.534095764160156 | Y: 12.647253036499023
New mouse position:
X: 163 | Y: 84
X: 24.534095764160156 | Y: 12.647253036499023
New mouse position:
X: 163 | Y: 84
X: 24.534095764160156 | Y: 12.647253036499023
New mouse position:
X: 163 | Y: 84
X: 24.534095764160156 | Y: 12.647253036499023
New mouse position:
X: 162 | Y: 84
X: 24.383533477783203 | Y: 12.647253036499023
New mouse position:
X: 162 | Y: 84
X: 24.383533477783203 | Y: 12.647253036499023
New mouse position:
X: 162 | Y: 84
X: 24.383533477783203 | Y: 12.647253036499023
New mouse position:
X: 162 | Y: 84
X: 24.383533477783203 | Y: 12.647253036499023
New mouse position:
X: 161 | Y: 84
X: 24.23297119140625 | Y: 12.647253036499023
New mouse position:
X: 161 | Y: 84
X: 24.23297119140625 | Y: 12.647253036499023
New mouse position:
X: 161 | Y: 83
X: 24.23297119140625 | Y: 12.496689796447754
New mouse position:
X: 161 | Y: 83
X: 24.23297119140625 | Y: 12.496689796447754
New mouse position:
X: 161 | Y: 83
X: 24.23297119140625 | Y: 12.496689796447754
New mouse position:
X: 160 | Y: 83
X: 24.082408905029297 | Y: 12.496689796447754
New mouse position:
X: 160 | Y: 83
X: 24.082408905029297 | Y: 12.496689796447754
New mouse position:
X: 160 | Y: 83
X: 24.082408905029297 | Y: 12.496689796447754
New mouse position:
X: 160 | Y: 83
X: 24.082408905029297 | Y: 12.496689796447754
New mouse position:
X: 160 | Y: 83
X: 24.082408905029297 | Y: 12.496689796447754
New mouse position:
X: 160 | Y: 83
X: 24.082408905029297 | Y: 12.496689796447754
New mouse position:
X: 159 | Y: 83
X: 23.931846618652344 | Y: 12.496689796447754
New mouse position:
X: 159 | Y: 83
X: 23.931846618652344 | Y: 12.496689796447754
New mouse position:
X: 159 | Y: 83
X: 23.931846618652344 | Y: 12.496689796447754
New mouse position:
X: 159 | Y: 83
X: 23.931846618652344 | Y: 12.496689796447754

The first line is the result of event.clientX and event.clientY, the second line the results after the svgPoint.matrixTransform(svg.getScreenCTM().inverse()). When I increase the zoom factor the number of events showing the same clientX coordinates increases. This means we have the rastering problem already in the mouse event itself: clientX and clientY already "perform" the stepping.

So, what would this mean for us? This means that the mouse event's coordinates are not screen pixels but already converted to some document's coordinate system.

But no idea still how to proceed from here.

uliska commented 10 years ago

Setting global staff size changes the viewBox parameters

uliska commented 10 years ago

http://stackoverflow.com/questions/23240504/understanding-coordinate-scaling-and-viewbox-in-a-pyqt-svg-javascript-project

uliska commented 10 years ago

OK, when dragging at a zoom of 100% I only get a number once for each mousemove. That seems to indicate that at this natural zoom 1 "client unit" is equivalent to 1 pixel. So actually these 0.15 may actually be the smallest unit when having 100%. This might indicate we can get somewhere by converting back and forth using the current zoom factor. Not sure about that, though

uliska commented 10 years ago

Another idea/approach: It may be that our issue comes from the fact that the zooming is done only at the viewing stage, in Python, and JavaScript doesn't know at all about it.

I think so because using pageX and even screenX instead of clientX produces exactly the same results. I think that when moving the mouse over a zoomed (magnified) window, the mouse is on the same position for some time, at least from the perspective of JavaScript.

If that's the case I don't see any viable solution short of moving the zooming functionality to the JavaScript part. I don't know if that would be as easy as setting a few scaling parameters to the SVG root object or would require manual repositioning of everything - which would be impossible.

PeterBjuhr commented 10 years ago

Sorry, I'm been busy during the day!

It seems to me that you are making roughly the same conclusions from all this that I'm doing:

The zooming doesn't behave in the way one would perhaps expect; it's a mere visual effect that doesn't affect many parameters. But if you think of it maybe this is common for screen zooming, you only get closer, the resolution isn't affected.

What we want is the editing to be done in a higher resolution so we can do a more fine-tuned editing. I see at the moment two ways how we can achieve this:

  1. We change the functionality of the zooming so it allows a higher resolution in the editing.
  2. We set up some kind of editing mode with a set resolution but higher than it is at the moment.

This was my rough response. I'll also comment in more detail...

uliska commented 10 years ago

And I'll be busy the evening. You may stream BBC 3 starting 8.30 to hear what I'm doing (although you'd probably not hear me personally ...)

Diese Nachricht wurde mit K-@ Mail gesendet.

uliska commented 10 years ago

You may look at the stackoverflow question. There is a comment I can't answer from here.

PeterBjuhr commented 10 years ago

Hm, I'm not sure where this might lead to. I've read about the viewBox attribute. And indeed changing this will change the scaling of the document. I have the impression that this would also break the relation of svg units to lilypond staff spaces.

Setting global staff size changes the viewBox parameters

Yes, that was one of the conclusions from my initial study. So if I'm judging this correctly the relation to the LilyPond staff spaces is preserved when changing the viewBox parameters just as it is preserved when changing the staff size.

But on the other hand I'm surprised about one thing: In theory the current viewBox setting should make the image show only a part of the document, but actually it displays the whole page. So it seems the viewBox is only working as a coordinate transformation system here.

When the viewBox values are adapted from the staff size value then it works because the page is reflown by LilyPond. But if we change the viewBox values afterwords it do make elements fall off the visual page (in my experience), that's therefore I proposed that also the width and height has to be changed...

PeterBjuhr commented 10 years ago

You may look at the stackoverflow question. There is a comment I can't answer from here.

I responded with an update with some more code...

PeterBjuhr commented 10 years ago

I assume these values [clientX/clientY] are not screen pixels but numbers in a unit of the SVG document and this is the source of our issue.

So what I would basically need is that clientX(etc.) gives me floating point results instead of rounded integers.

It seems they are in fact screen pixels:

pageX, pageY, screenX, screenY, clientX and clientY returns a number which indicates the number of physical pixels a point is from the reference point. http://stackoverflow.com/questions/6073505/what-is-the-difference-between-screenx-y-clientx-y-and-pagex-y

Which means that they aren't rounded off.

As I see it, the relation between screen pixels and SVG coordinates stays the same when we zoom in. The pixels are only made bigger. Does that make sense?