Proposal: Canvas Interaction Enhancements

Arjen Hiemstra djfreestyler at gmail.com
Mon May 14 13:54:35 UTC 2012


Warning: Long mail ahead! ;)

Introduction
-------------------

I have been discussing Krita's canvas interaction with Boudewijn recently and 
he suggested I do some research and brainstorming on it. This proposal is the 
result of that research and brainstorming. It discusses an issue with the 
current behaviour of input and a proposed change to fix the issue.

Current Situation
--------------------------

There are currently several actions within Krita that deal directly with 
interaction with the canvas, for example panning, rotating and zooming the 
canvas. Currently, these actions are handled in different ways depending on 
what the current tool is and in several cases are simply duplicated across 
tools. For example, when you want to pan the canvas, you either use the pan 
tool, or you use the panning "embedded" within another tool. Zooming can be 
similarly performed in different ways while rotating the canvas can be done 
only by the pan tool or by using keyboard shortcuts.

This scattering of functions across the different tools obviously not ideal. In 
the long run, it will only serve to confuse new users and hamper the work flow 
of experienced users. In addition, the code behind it is not really extensible 
or modular, which means that the implementation of new features may be 
hampered or even impossible.

Detailed List of Actions
----------------------------------

The following is a list of all actions I would define as "canvas interaction" 
actions, that is, any action that interacts directly with the canvas. It also 
lists their associated key/button when using the Brush tool.

1. Tool Invocation (Paint) - Left Mouse
2. Pan Canvas - Space + Left Mouse, Middle Mouse
3. Zoom Canvas - Mouse Wheel, Ctrl + - and Ctrl + =
4. Rotate Canvas - Ctrl + [ and Ctrl + ]
5. Pick Colour - Ctrl + Left Mouse
6. Pick Duplicate Position - Ctrl + Left Mouse
7. Change Brush Size - Shift + Left Mouse (Drag)
8. Pick Mirror Axis - Ctrl + Shift + Left Mouse
9. Open Quick Select Menu - Right Mouse

Proposed Changes
----------------------------

The first and foremost change I propose is to define a set of universal actions 
that interact with the canvas and a default set of shortcuts for using these 
actions, trying to stay as close to current default behaviour as possible. I 
have listed a set of proposed actions below, of course this set is not set in 
stone. This step should hopefully result in few user-visible changes, apart 
from the mentioned unification. (Possibly also the removal of the Pan and Zoom 
tools, but that is debatable.)

Once the universal actions have been implemented, I propose to implement a 
configuration page to configure these actions, specifically to make it possible 
to assign several alternatives to these actions. For example, for zooming, it 
would be great to be able to use at least four different methods of input: 
mouse button and drag, mouse wheel, keyboard shortcuts and a pinch gesture for 
tablets that support those.

The third change I would look at implementing is a somewhat longer term goal: 
support for touch gestures like pinching. These are supported by several newer 
Wacom tablets but they are something that are hard to support within Krita, 
due to several reasons, the lack of a unified input handling method being only 
one of them. This will need some additional research since the state of 
gesture support on multiple levels within the platform is currently unknown.

Benefits
--------------

The primary benefit of the proposed changes is to have a unified way of dealing 
with the canvas. Rather than every tool doing its own thing and needing to 
duplicate a lot of functionality, there is a central place to handle input and 
it can decide what happens with that input. This allows for more flexibility 
and less overhead when implementing new functionality, like the proposed touch 
support. In addition, due to the more centralised nature, it allows for more 
configurability since there is now a single place that determines what happens 
on which input, which allows experienced users to more easily tweak their work 
flow.

Proposed Universal Actions
-----------------------------------------

The following list is a proposed list of universal actions with their default 
associated key/button.

1. Tool Invocation - Left Mouse
2. Alternate Tool Invocation (1) - Ctrl + Left Mouse
3. Change Tool Primary Setting (2) - Shift + Left Mouse
4. Open Quick Select Menu - Right Mouse 
5. Pan Canvas - Middle Mouse
6. Zoom Canvas - Ctrl + Middle Mouse, Mouse Wheel
7. Rotate Canvas - Shift + Middle Mouse
8. Set Mirror Axis - Ctrl + Shift + Left Mouse (3)

Notes:
(1): The default of this action would be to pick a colour from the canvas, 
however, this does not make sense for all tools. Therefore, it should be 
possible to override this. This would make it possible for - for example - the 
duplicate brush engine to use this same action to select the duplicate 
position rather than pick a colour. 
(2): This is a very tool dependant action, the only current implementation of 
this is changing the brush size for the paint brush. 
(3): I am unsure whether this belongs as a "universal" action. I guess this 
should be discussed with people who use mirroring often, but one way of 
handling mirror axes would be to use drag-able helper lines.

Technical Implementation
-----------------------------------------

The most significant change this proposal needs implementation wise is a change 
in how the canvas handles input events. Instead of passing all actions 
directly to the tool proxy and then to the tool, this proposal adds a new 
level of indirection. Input events are passed on to a central class, I will 
call it the input handler for now. The input handler has a list of all the 
universal actions available. It uses the input from the canvas to decide what 
action to pass the input on to, thereby making it possible to configure this. 

Using the input to determine the action avoids looping through the entire set 
of actions on every input action, a potentially costly operation. In addition, 
since the input layer passes input on to actions and those pass it on to 
tools, there is no need for tools to re-implement common functionality for 
canvas actions, instead they can simply deal with whatever needs to happen 
when the tool is invoked.

I am currently undecided whether universal actions should be plugins. It 
probably makes sense on the long run, since it would ease adding new universal 
actions if needed. However, I do think it is a relatively trivial task to make 
them plugins and this can be done at a later time. Also, it might make sense 
to consider a more modular input handling system, primarily to make it easier 
to integrate third-party hardware. I do consider these follow-up topics, 
however.

P.S.: If this mail seems awfully formal, that's mostly because it allowed me 
to more easily structure my thoughts. I am not usually so formal. ;)




More information about the kimageshop mailing list