Dev:Ref/Proposals/UI/Modal interaction improvements api

提供: wiki
< Dev:Ref‎ | Proposals‎ | UI
移動先: 案内検索

Improving Modal Interaction API

Current Problems

Modal operators are a common way to develop advanced tools in Blender with their own subset of options and capabilities. A few key examples include the Knife mesh tool and Fly Mode navigation. However, modals currently are blocking, in that they block any other events/operators from being fired. For example, unless explicitly set within the operator you cannot navigate the 3D View while inside a modal. The way events are currently passed through is very cumbersome unless it's restricted to just a few events.

Problems:

  • Passing through events is cumbersome
  • Passing through events is very specific, and generally locked to the keyboard press rather than the operator.
    • this makes it problematic to support things like navigation as the passthrough breaks the moment the keymap is changed
  • Any changes to the default keymap often breaks passthrough events in existing modals
  • New operators to a group (such as navigation) does not automatically get supported by modal operators (due to them needing passed through explicitly)


Proposed Solution

One possible solution to this problem is to group operators by type using a tagging system. The tags would likely be defined during the registration of the operator (perhaps with bl_tag). For example, navigation operators would be tagged with "navigation", such that a add-on developer could allow all navigation events to pass through rather than explicitly setting them one by one.

The tagging might look like:

    class ViewNavigator(bpy.types.Operator):
        bl_idname = "view3d.view_navigator"
        bl_label  = "View Navigator"
        bl_tags =  {'NAVIGATE'}

Setting the pass through within the operator python code might look like:

    def modal(self, context, event):
        if context.window.event_matches(event, {'NAVIGATE', 'SELECT'}):
            return {'PASS_THROUGH'}

So rather than checking for explicit keyboard events to pass through we instead check for groups of operators, greatly lessening the workload and complexity of allowing more interaction within modals.

The benefit to this is it would allow add-on developers to easily pass through vital events, such as navigation, rather than having to list out all of the possible events like we currently do. To put it into perspective, here is a list that includes most (not all) navigation keyboard events that need to be passed through during a modal:

        events_numpad = {
            'NUMPAD_1',       'NUMPAD_2',       'NUMPAD_3',
            'NUMPAD_4',       'NUMPAD_5',       'NUMPAD_6',
            'NUMPAD_7',       'NUMPAD_8',       'NUMPAD_9',
            'CTRL+NUMPAD_1',  'CTRL+NUMPAD_2',  'CTRL+NUMPAD_3',
            'CTRL+NUMPAD_4',  'CTRL+NUMPAD_5',  'CTRL+NUMPAD_6',
            'CTRL+NUMPAD_7',  'CTRL+NUMPAD_8',  'CTRL+NUMPAD_9',
            'SHIFT+NUMPAD_1', 'SHIFT+NUMPAD_2', 'SHIFT+NUMPAD_3',
            'SHIFT+NUMPAD_4', 'SHIFT+NUMPAD_5', 'SHIFT+NUMPAD_6',
            'SHIFT+NUMPAD_7', 'SHIFT+NUMPAD_8', 'SHIFT+NUMPAD_9',
            'NUMPAD_PLUS', 'NUMPAD_MINUS', # CTRL+NUMPAD_PLUS and CTRL+NUMPAD_MINUS are used elsewhere
            'NUMPAD_PERIOD',
        }

That doesn't even account for trackpad, NDOF, or other types of navigation events. Additionally it does not account for custom keymaps, or even default presets like Max or Maya.

Benefits to Proposed Solution

  1. Simpler scripting API for developing modal operators
  2. A more reliable keymap that breaks fewer tools when changed
  3. More comprehensive modal operators that ensure navigation (and other events) are more fully supported. Including but not limited to mouse, keyboard, and NDOF navigation.
  4. Ability for users to customize their keymaps or change presets while maintaining consistent interaction within modals

Possible Problems

With any change like this there's bound to be other issues that may or may not need to be addressed. Some of these are more unique issues of their own while others are directly related:

Keymap conflicts within keymaps and modal operators

If a modal operator has defined specific keys for sub-operations then these keys might conflict with an event that's passed through a tag group. For example, a modal might use a key that the user has also set in their custom keymap. This scenario is a bit corner-case and may be unavoidable, to a degree, but should be considered.

Another scenario where keymap conflicts might arise is if a tag group is too encompassing and takes over most keys. This is something that should likely be addressed through moderation, though, by prudently tagging operators.

Operation conflicts within modals and passed through events

A developer may utilize a specific key within their modal that then conflicts with an event that is passed through as part of a tag group. For example, they may use LMB Template-LMB.png to control an operation, all the while passing through selection events. In this scenario it's probably best to also support excluding specific events from a tag.