1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
/**
* @file llviewerkeyboard.h
* @brief LLViewerKeyboard class header file
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLVIEWERKEYBOARD_H
#define LL_LLVIEWERKEYBOARD_H
#include "llkeyboard.h" // For EKeystate
#include "llinitparam.h"
const S32 MAX_NAMED_FUNCTIONS = 100;
const S32 MAX_KEY_BINDINGS = 128; // was 60
class LLNamedFunction
{
public:
LLNamedFunction() : mFunction(NULL) { };
~LLNamedFunction() { };
std::string mName;
LLKeyFunc mFunction;
};
class LLKeyboardBinding
{
public:
KEY mKey;
MASK mMask;
bool mIgnoreMask; // whether CTRL/ALT/SHIFT should be checked
LLKeyFunc mFunction;
};
class LLMouseBinding
{
public:
EMouseClickType mMouse;
MASK mMask;
bool mIgnoreMask; // whether CTRL/ALT/SHIFT should be checked
LLKeyFunc mFunction;
};
typedef enum e_keyboard_mode
{
MODE_FIRST_PERSON,
MODE_THIRD_PERSON,
MODE_EDIT,
MODE_EDIT_AVATAR,
MODE_SITTING,
MODE_COUNT
} EKeyboardMode;
class LLWindow;
void bind_keyboard_functions();
class LLViewerKeyboard
{
public:
struct KeyBinding : public LLInitParam::Block<KeyBinding>
{
Mandatory<std::string> key,
mask,
command;
Optional<std::string> mouse; // Note, not mandatory for the sake of backward campatibility
Optional<bool> ignore;
KeyBinding();
};
struct KeyMode : public LLInitParam::Block<KeyMode>
{
Multiple<KeyBinding> bindings;
KeyMode();
};
struct Keys : public LLInitParam::Block<Keys>
{
Optional<KeyMode> first_person,
third_person,
edit,
sitting,
edit_avatar;
Keys();
};
LLViewerKeyboard();
BOOL handleKey(KEY key, MASK mask, BOOL repeated);
BOOL handleKeyUp(KEY key, MASK mask);
S32 loadBindings(const std::string& filename); // returns number bound, 0 on error
S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error
EKeyboardMode getMode() const;
BOOL modeFromString(const std::string& string, S32 *mode) const; // False on failure
BOOL mouseFromString(const std::string& string, EMouseClickType *mode) const;// False on failure
void scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const;
// handleMouse() records state, scanMouse() goes through states, scanMouse(click) processes individual saved states after UI is done with them
BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
void LLViewerKeyboard::scanMouse();
private:
bool scanKey(const LLKeyboardBinding* binding,
S32 binding_count,
KEY key,
MASK mask,
BOOL key_down,
BOOL key_up,
BOOL key_level,
bool repeat) const;
enum EMouseState
{
MOUSE_STATE_DOWN, // key down this frame
MOUSE_STATE_CLICK, // key went up and down in scope of same frame
MOUSE_STATE_LEVEL, // clicked again fast, or never released
MOUSE_STATE_UP, // went up this frame
MOUSE_STATE_SILENT // notified about 'up', do not notify again
};
bool scanMouse(EMouseClickType click, EMouseState state) const;
bool scanMouse(const LLMouseBinding *binding,
S32 binding_count,
EMouseClickType mouse,
MASK mask,
EMouseState state) const;
S32 loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, S32 mode);
BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const bool ignore, const std::string& function_name);
BOOL bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const bool ignore, const std::string& function_name);
void resetBindings();
// Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here
// We process specific keys first, then keys that should ignore mask.
// This way with W+ignore defined to 'forward' and with ctrl+W tied to camera,
// pressing undefined Shift+W will do 'forward', yet ctrl+W will do 'camera forward'
// With A defined to 'turn', shift+A defined to strafe, pressing Shift+W+A will do strafe+forward
S32 mKeyBindingCount[MODE_COUNT];
S32 mKeyIgnoreMaskCount[MODE_COUNT];
S32 mMouseBindingCount[MODE_COUNT];
S32 mMouseIgnoreMaskCount[MODE_COUNT];
LLKeyboardBinding mKeyBindings[MODE_COUNT][MAX_KEY_BINDINGS];
LLKeyboardBinding mKeyIgnoreMask[MODE_COUNT][MAX_KEY_BINDINGS];
LLMouseBinding mMouseBindings[MODE_COUNT][MAX_KEY_BINDINGS];
LLMouseBinding mMouseIgnoreMask[MODE_COUNT][MAX_KEY_BINDINGS];
typedef std::map<U32, U32> key_remap_t;
key_remap_t mRemapKeys[MODE_COUNT];
std::set<KEY> mKeysSkippedByUI;
BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI
// This is indentical to what llkeyboard does (mKeyRepeated, mKeyLevel, mKeyDown e t c),
// just instead of remembering individually as bools, we record state as enum
EMouseState mMouseLevel[CLICK_COUNT]; // records of key state
};
extern LLViewerKeyboard gViewerKeyboard;
#endif // LL_LLVIEWERKEYBOARD_H
|