Page MenuHome

Gesture based multi-button dragging/editing.
AbandonedPublic

Authored by Campbell Barton (campbellbarton) on Jan 29 2014, 5:35 AM.

Details

Summary

This patch adds the ability to use vertical gestures to define multiple buttons to draw or type values into.

Also, this sounds more complicated then it really is, recommend testing the patch out before jumping to conclusions.

Usage

  • click on the first button you want to modify, then drag up/down to another grouped button you want to drag)
  • notice only the buttons highlight and un-highlight as you drag.
  • drag horizontally to edit the highlighed buttons OR let go of the mouse button and type in a value (its applied to all).

Pros:

  • fast to access, applies to all buttons without modifications to layout or cluttering the interface with more buttons.
  • Compared to adding a button that links values...
  • - No extra UI clutter or having to keep track of the state of which buttons are linked (not so simple for dynamically generated UI's)
  • - One click instead of 3 (link, drag, unlink)
  • - You can easily select a subset of the buttons to drag (just XY for eg).

Cons:

  • Not discoverable (This can be resolved by having visual hints around grouped buttons when initiating the drag)
  • The L (or '˥' - flipped) shaped motion used to select buttons to drag, then to drag, may be hard for some users (maybe they drag vertically by accident sometimes, or wish to drag vertically but the gesture isn't detected...)
  • This only works when buttons are stacked vertically (which is mostly the case, but there are exceptions).

Todo:

If this patch is accepted, some todo's...

  • Draw some indication that vertical drag is possible so this isnt a totally hidden feature.
  • Color is currently hard coded to a white highlight, perhaps should use theme color for highlight, or a different theme color (minor detail).
  • Support for maintaining aspect ratio with render resolution and object scale (perhaps with an RNA flag).

Technical Notes:

  • To tweak behavior - modify DRAG_MULTINUM_THRESHOLD_DRAG_X, DRAG_MULTINUM_THRESHOLD_DRAG_Y and DRAG_MULTINUM_THRESHOLD_VERTICAL, comments explain how they work.
  • we could have a more generic way to modify and restore a list of button values.
  • referencing buttons by center-point isn't ideal, could use pointers and update them in ui_but_update_from_old_block
  • ifdef'd in for now, this kind of feature makes changes it quite a few areas and I'd like to quickly be able to disable (as with drag-toggle)

Credits:

extended from an initial patch developed with Alex Fraser - @Alex Fraser (z0r), modified based on feedback from @Daniel Salazar (zanqdo) and @Jonathan Williamson (carter2422)

Diff Detail

Event Timeline

The patch works well*; I think it gives a good user experience. I didn't need to tweak the threshold values; they felt quite nice.

I was surprised that the offsets of the original values are maintained while dragging. It's a nice touch, especially for fields like frame start/end. Some suggestions for this feature (offsets):

  • It would be nice to be able to turn offsets off (just use the same value for all). Perhaps a modifier key would be good for this.
  • Conversely, it would be nice if typing a value used the offsets too. I'm not sure how to toggle this, though - a modifier key might be cumbersome in this case.
  • I agree that certain fields shouldn't use constant offsets: scale and render resolution should be linearly proportional instead. Yep, we could use an RNA flag for that.
  • Actually I found a bug! It doesn't work with Object.dimensions in the properties shelf: if I drag from x to z, only x and z appear to be updated (not y), and on release, only z is actually applied.

Some feedback from trying this patch:

  • I would expect the other selected buttons to get the same color as the first button. Rather than highlighted they could have the "inner selected" color just like the first button.
  • The L shaped motion is a bit strange, to me it feels like there's a delay when you drag down and to the side, not ideal if you only want to drag a small distance. Ideally you could do that without the delay but I don't know how much it would interfere with regular dragging.
  • It would make sense if you could type in numbers the same way, drag down and release, then start typing.

Overall I think this is a good idea.

Campbell Barton (campbellbarton) updated this revision to Unknown Object (????).Jan 30 2014, 10:05 PM

Updated patch,

changes:

  • typing in values now shows for all buttons (code for this is a bit messy...)
  • improved detection of changing mouse direction (shouldn't feel glitchy anymore)
  • auto-keyframe now works as expected.
  • sliders now work.
  • now makes buttons same color as editing (default theme only - TODO use theme colors)

@Alex Fraser (z0r) re: Object.dimensions This is really a bug in blender, python devs also found this and complained that it doesnt work when setting values at once.

obj.dimensions = 1, 2, 3

... also gives same problem. the way its applies breaks setting multiple values at once.

As noted on IRC, there's a nasty bug that causes the cursor position to not reset after dragging. This results in the click location after dragging being wrong.

Video showing problem:
http://cl.ly/TekO

Note: in the video watch towards the end, it's a little hard to get right.

Campbell Barton (campbellbarton) updated this revision to Unknown Object (????).Jan 30 2014, 11:21 PM

fixed for but editing numbers not applying to otehrs

I totally love it.
It's simple, elegant and even discoverable (by accident).
As far as I can tell the only exception where this wouldn't work is the mapping node. But it is not clear to me anyway why we don't have horizontal buttons there. It breaks the convention, and I don't see a good reason why we cannot have vertical stacked sliders there. That node is quite large anyway. Maybe this could be changed?

developer notes:

There are some things I'd like to change in this patch.

button references:

the main thing I'd like to change is how buttons are referenced, currently the location is stored and each time the button is referenced its looked up be the original location.

to me this seems a bit clumsy and I would rather store pointers to the buttons directly, however this gives the problem that the pointers become invalid on redraw.

so I would propose to have a simple set of functions to manage button references which can be used by any event handler or operator which needs to reference buttons that redraw.

handle = ui_but_modalstore_create(ar);

/* register any number of buttons */
ui_but_modalstore_register(handle, &but);  /* the button will be automatically updated */

/* modal tool runs and can access button pointers... */

ui_but_modalstore_distroy(handle);

This would use something like ui_but_update_from_old_block to ensure each handle's pointers were valid or NULL'd in the rare case a buttons freed.

Multi-button editing display:

This is horrible - the way one button looks for the editing button and displays with its string, the only thing that makes this slightly ok is that the checks are only done when UI_BUT_DRAG_MULTI is set, so at least the hack is isolated to a corner case... even so, I can't really think of a good way to do this, and would be happy to simply draw nothing in this case (so non active buttons are blanked out). not quite as nice but you don't NEED to see the text in all buttons for this to work.

Multi-drag is great.
Is it possible to do it work with shapekeys in lists ?

I agree with zor. It is partically usefull for start/end frame ranges.
But it does not work with most of start/end frame ranges because they are horizontal in the UI.
(timeline, physics caches)

Could it be possible to select these both values at same time by clicking on black separation line ?

This is amazing :)

One thing I think would make this even better is if the values were edited relatively if math expressions are used:

For instance, If I click and vertical drag select the X and Y values, as soon as I release LMB both values are set to the value of the button I initially clicked on (in this case the top one):

I think it would be more intuitive if the values were kept separate until the edit is confirmed, then:

  • If no math expressions are used the other buttons are set to the value of the initially clicked button. (almost current behavior, but I'm suggesting that the actual change happen after the edit is confirmed)
  • If math expressions are used, then the expression is evaluated for each individual button, so:

Pros:

  • Allows easy relative editing with numerical input (render resolution is just one example of a use case)
  • Still allows an easy way to set all related values to the same value (click > drag > enter)

Cons:

  • Loses the real time display of the result in the secondary buttons (there might be some ways around this though).

One other thing I thought of is the fact that you can de-select a button.

For example, if you want to edit the X and the Z location of an object you must still edit each individually, since the Y is between the X and Z.
I haven't thought of a good way around this though.

@Ellwood Zwovic (gandalf3), yes - in fact I wanted to do this, but found it not so simple to implement.

If others agree its an improvement it can at least be a TODO item.

BTW, not to be picky or anything, but the "white" is misspelled: "Color is currently hard coded to a wight highlight". In English, "wight" refers to a person.
:)

@Campbell Barton (campbellbarton) I saw your avatar and thought of this: Ophiuchus
Happy coding!
:)