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