summaryrefslogtreecommitdiff
path: root/indra/newview/llkeyconflict.h
blob: 00fbe18863dcc6e7176906d3284645578d1a68a9 (plain)
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/** 
 * @file llkeyconflict.h
 * @brief 
 *
 * $LicenseInfo:firstyear=2019&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2019, 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_LLKEYCONFLICT_H
#define LL_LLKEYCONFLICT_H

#include "llkeybind.h"
#include "llviewerkeyboard.h"


class LLKeyConflict
{
public:
    LLKeyConflict() : mAssignable(true), mConflictMask(U32_MAX) {} //temporary assignable, don't forget to change once all keys are recorded
    LLKeyConflict(bool assignable, U32 conflict_mask)
        : mAssignable(assignable), mConflictMask(conflict_mask) {}
    LLKeyConflict(const LLKeyBind &bind, bool assignable, U32 conflict_mask)
        : mAssignable(assignable), mConflictMask(conflict_mask), mKeyBind(bind) {}

    LLKeyData getPrimaryKeyData() { return mKeyBind.getKeyData(0); }
    LLKeyData getKeyData(U32 index) { return mKeyBind.getKeyData(index); }
    void setPrimaryKeyData(const LLKeyData& data) { mKeyBind.replaceKeyData(data, 0); }
    void setKeyData(const LLKeyData& data, U32 index) { mKeyBind.replaceKeyData(data, index); }
    bool canHandle(EMouseClickType mouse, KEY key, MASK mask) { return mKeyBind.canHandle(mouse, key, mask); }

    LLKeyBind mKeyBind;
    bool mAssignable; // whether user can change key or key simply acts as placeholder
    U32 mConflictMask;
};

class LLKeyConflictHandler
{
public:

    enum ESourceMode // partially repeats e_keyboard_mode
    {
        MODE_FIRST_PERSON,
        MODE_THIRD_PERSON,
        MODE_EDIT,
        MODE_EDIT_AVATAR,
        MODE_SITTING,
        MODE_GENERAL, // for settings from saved settings
        MODE_COUNT
    };

    const U32 CONFLICT_NOTHING = 0;
    // at the moment this just means that key will conflict with everything that is identical
    const U32 CONFLICT_ANY = U32_MAX;

    // todo, unfortunately will have to remove this and use map/array of strings
    enum EControlTypes
    {
        CONTROL_VIEW_ACTIONS = 0, // Group control, for visual representation in view, not for use
        CONTROL_ABOUT,
        CONTROL_ORBIT,
        CONTROL_PAN,
        CONTROL_WORLD_MAP,
        CONTROL_ZOOM,
        CONTROL_INTERACTIONS, // Group control, for visual representation
        CONTROL_BUILD,
        //CONTROL_DRAG,
        CONTROL_EDIT,
        //CONTROL_MENU,
        CONTROL_OPEN,
        CONTROL_TOUCH,
        CONTROL_WEAR,
        CONTROL_MOVEMENTS, // Group control, for visual representation
        CONTROL_MOVETO,
        CONTROL_TELEPORTTO,
        CONTROL_FORWARD,
        CONTROL_BACKWARD,
        CONTROL_LEFT, // Check and sinc name with real movement names
        CONTROL_RIGHT,
        CONTROL_LSTRAFE,
        CONTROL_RSTRAFE,
        CONTROL_JUMP,
        CONTROL_DOWN,
        //CONTROL_RUN,
        CONTROL_TOGGLE_RUN,
        CONTROL_TOGGLE_FLY,
        CONTROL_SIT,
        CONTROL_STOP,
        CONTROL_CAMERA, // Group control, for visual representation
        CONTROL_LOOK_UP,
        CONTROL_LOOK_DOWN,
        CONTROL_CAMERA_FORWARD,
        CONTROL_CAMERA_BACKWARD,
        CONTROL_CAMERA_FFORWARD,
        CONTROL_CAMERA_FBACKWARD,
        CONTROL_CAMERA_FSITTING,
        CONTROL_CAMERA_BSITTING,
        CONTROL_CAMERA_SOVER,
        CONTROL_CAMERA_SUNDER,
        CONTROL_CAMERA_SOVER_SITTING,
        CONTROL_CAMERA_SUNDER_SITTING,
        CONTROL_CAMERA_PANUP,
        CONTROL_CAMERA_PANDOWN,
        CONTROL_CAMERA_PANLEFT,
        CONTROL_CAMERA_PANRIGHT,
        CONTROL_CAMERA_PANIN,
        CONTROL_CAMERA_PANOUT,
        CONTROL_CAMERA_SPIN_CCW,
        CONTROL_CAMERA_SPIN_CW,
        CONTROL_CAMERA_SPIN_CCW_SITTING,
        CONTROL_CAMERA_SPIN_CW_SITTING,
        CONTROL_EDIT_TITLE, // Group control, for visual representation
        CONTROL_EDIT_AV_SPIN_CCW,
        CONTROL_EDIT_AV_SPIN_CW,
        CONTROL_EDIT_AV_SPIN_OVER,
        CONTROL_EDIT_AV_SPIN_UNDER,
        CONTROL_EDIT_AV_MV_FORWARD,
        CONTROL_EDIT_AV_MV_BACKWARD,
        CONTROL_MEDIACONTENT, // Group control, for visual representation
        CONTROL_PAUSE_MEDIA, // Play pause
        CONTROL_ENABLE_MEDIA, // Play stop
        CONTROL_VOICE, // Keep pressing for voice to be ON
        CONTROL_TOGGLE_VOICE, // Press once to ON/OFF
        CONTROL_START_CHAT, // Press once to ON/OFF
        CONTROL_START_GESTURE, // Press once to ON/OFF
        CONTROL_RESERVED, // Special group control, controls that are disabled by default and not meant to be changed
        CONTROL_DELETE,
        CONTROL_RESERVED_MENU,
        CONTROL_RESERVED_SELECT,
        CONTROL_SHIFT_SELECT,
        CONTROL_CNTRL_SELECT,
        CONTROL_NUM_INDICES // Size, always should be last
    };

    // Note: missed selection and edition commands (would be really nice to go through selection via MB4/5 or wheel)

    LLKeyConflictHandler();
    LLKeyConflictHandler(ESourceMode mode);

    bool canHandleControl(EControlTypes control_type, EMouseClickType mouse_ind, KEY key, MASK mask);
    bool canHandleKey(EControlTypes control_type, KEY key, MASK mask);
    bool canHandleMouse(EControlTypes control_type, EMouseClickType mouse_ind, MASK mask);
    bool canHandleMouse(EControlTypes control_type, S32 mouse_ind, MASK mask); //Just for convinience
    bool canAssignControl(EControlTypes control_type);
    bool registerControl(EControlTypes control_type, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts?

    LLKeyData getControl(EControlTypes control_type, U32 data_index);

    static std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata);
    static std::string getControlName(EControlTypes control_type);
    std::string getControlString(EControlTypes control_type, U32 data_index);


    // Drops any changes loads controls with ones from 'saved settings' or from xml
    void loadFromSettings(ESourceMode load_mode);
    // Saves settings to 'saved settings' or to xml
    void saveToSettings();

    LLKeyData getDefaultControl(EControlTypes control_type, U32 data_index);
    // Resets keybinding to default variant from 'saved settings' or xml
    void resetToDefault(EControlTypes control_type, U32 index);
    void resetToDefault(EControlTypes control_type);
    // resets current mode to defaults, 
    void resetToDefaults();

    bool empty() { return mControlsMap.empty(); }
    void clear();

    bool hasUnsavedChanges() { return mHasUnsavedChanges; }
    void setLoadMode(ESourceMode mode) { mLoadMode = mode; }
    ESourceMode getLoadMode() { return mLoadMode; }

private:
    void resetToDefaultAndResolve(EControlTypes control_type, bool ignore_conflicts);
    void resetToDefaults(ESourceMode mode);

    // at the moment these kind of control is not savable, but takes part will take part in conflict resolution
    void registerTemporaryControl(EControlTypes control_type, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask);

    typedef std::map<EControlTypes, LLKeyConflict> control_map_t;
    void loadFromSettings(const LLViewerKeyboard::KeyMode& keymode, control_map_t *destination);
    void loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);
    void resetKeyboardBindings();
    void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values
    // returns false in case user is trying to reuse control that can't be reassigned
    bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask);

    control_map_t mControlsMap;
    control_map_t mDefaultsMap;
    bool mHasUnsavedChanges;
    ESourceMode mLoadMode;
};


#endif  // LL_LLKEYCONFLICT_H