diff options
-rw-r--r-- | indra/llcommon/llkeybind.cpp | 76 | ||||
-rw-r--r-- | indra/llcommon/llkeybind.h | 19 | ||||
-rw-r--r-- | indra/llui/llscrolllistcell.cpp | 24 | ||||
-rw-r--r-- | indra/llui/llscrolllistcell.h | 2 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 2 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 19 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.cpp | 164 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.h | 4 | ||||
-rw-r--r-- | indra/newview/llkeyconflict.cpp | 128 | ||||
-rw-r--r-- | indra/newview/llkeyconflict.h | 42 | ||||
-rw-r--r-- | indra/newview/lltool.cpp | 4 | ||||
-rw-r--r-- | indra/newview/lltoolpie.cpp | 17 | ||||
-rw-r--r-- | indra/newview/lltoolpie.h | 4 | ||||
-rw-r--r-- | indra/newview/llviewerkeyboard.cpp | 473 | ||||
-rw-r--r-- | indra/newview/llviewerkeyboard.h | 10 | ||||
-rw-r--r-- | indra/newview/llviewerwindow.cpp | 8 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.cpp | 70 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.h | 10 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/panel_preferences_controls.xml | 5 |
19 files changed, 612 insertions, 469 deletions
diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index 0eca289d4b..ff88a9c9aa 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -218,13 +218,17 @@ bool LLKeyBind::isEmpty() const LLSD LLKeyBind::asLLSD() const { + S32 last = mData.size() - 1; + while (mData[last].empty()) + { + last--; + } + LLSD data; - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + for (S32 i = 0; i <= last; ++i) { - if (!iter->isEmpty()) - { - data.append(iter->asLLSD()); - } + // append even if empty to not affect visual representation + data.append(mData[i].asLLSD()); } return data; } @@ -280,6 +284,43 @@ bool LLKeyBind::hasKeyData(const LLKeyData& data) const return hasKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks); } +bool LLKeyBind::hasKeyData(U32 index) const +{ + return mData.size() > index; +} + +S32 LLKeyBind::findKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const +{ + if (mouse != CLICK_NONE || key != KEY_NONE) + { + for (S32 i = 0; i < mData.size(); ++i) + { + if (mData[i].mKey == key + && mData[i].mMask == mask + && mData[i].mMouse == mouse + && mData[i].mIgnoreMasks == ignore) + { + return i; + } + } + } + return -1; +} + +S32 LLKeyBind::findKeyData(const LLKeyData& data) const +{ + return findKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks); +} + +LLKeyData LLKeyBind::getKeyData(U32 index) const +{ + if (mData.size() > index) + { + return mData[index]; + } + return LLKeyData(); +} + bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) { if (!hasKeyData(mouse, key, mask, ignore)) @@ -344,28 +385,29 @@ void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index) } } } - if (mData.size() > index) + if (mData.size() <= index) { - mData[index] = data; - } - else - { - mData.push_back(data); + mData.resize(index + 1); } + mData[index] = data; } -bool LLKeyBind::hasKeyData(U32 index) const +void LLKeyBind::resetKeyData(S32 index) { - return mData.size() > index; + if (mData.size() > index) + { + mData[index].reset(); + } } -LLKeyData LLKeyBind::getKeyData(U32 index) const +void LLKeyBind::trimEmpty() { - if (mData.size() > index) + S32 last = mData.size() - 1; + while (last >= 0 && mData[last].empty()) { - return mData[index]; + mData.erase(mData.begin() + last); + last--; } - return LLKeyData(); } U32 LLKeyBind::getDataCount() diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 25179a57f3..39cb668aac 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -74,17 +74,26 @@ public: bool canHandleKey(KEY key, MASK mask) const; bool canHandleMouse(EMouseClickType mouse, MASK mask) const; - bool LLKeyBind::hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; - bool LLKeyBind::hasKeyData(const LLKeyData& data) const; + // contains specified combination + bool hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; + bool hasKeyData(const LLKeyData& data) const; + bool hasKeyData(U32 index) const; + + // index of contained LLKeyData + S32 findKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const; + S32 findKeyData(const LLKeyData& data) const; + + LLKeyData getKeyData(U32 index) const; // these methods enshure there will be no repeats bool addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore); bool addKeyData(const LLKeyData& data); void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index); void replaceKeyData(const LLKeyData& data, U32 index); - bool hasKeyData(U32 index) const; - void clear() { mData.clear(); }; - LLKeyData getKeyData(U32 index) const; + void resetKeyData(S32 index); + void clear() { mData.clear(); } + // if there any empty LLKeyData in the end of the array, remove them + void trimEmpty(); U32 getDataCount(); private: diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 0a33ee8878..d6627a6957 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -196,7 +196,14 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p) void LLScrollListText::highlightText(S32 offset, S32 num_chars) { mHighlightOffset = offset; - mHighlightCount = num_chars; + mHighlightCount = llmax(0, num_chars); +} + +//virtual +void LLScrollListText::setHighlighted(bool highlighted) +{ + mHighlightOffset = 0; + mHighlightCount = highlighted ? -1 : 0; } //virtual @@ -296,6 +303,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col if (mHighlightCount > 0) { + // Highlight text S32 left = 0; switch(mFontAlignment) { @@ -314,11 +322,15 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, 1); mRoundedRectImage->draw(highlight_rect, highlight_color); - /*LLRect highlight_rect(left - 2, - mFont->getLineHeight() + 2, - left + getWidth() + 2, - 1); - mRoundedRectImage->draw(highlight_rect, LLColor4::black);*/ + } + else if (mHighlightCount < 0) + { + // Highlight whole cell + LLRect highlight_rect(0, + getHeight(), + getWidth() - 1, + -1); + gl_rect_2d(highlight_rect, LLColor4(0.38f, 0.694f, 0.573f, 0.35f)); } // Try to draw the entire string diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 1604a9b1dc..b4bb14bcf1 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -103,6 +103,7 @@ public: virtual BOOL getVisible() const { return TRUE; } virtual void setWidth(S32 width) { mWidth = width; } virtual void highlightText(S32 offset, S32 num_chars) {} + virtual void setHighlighted(bool highlighted) {} virtual BOOL isText() const { return FALSE; } virtual BOOL needsToolTip() const { return ! mToolTip.empty(); } virtual void setColor(const LLColor4&) {} @@ -140,6 +141,7 @@ public: /*virtual*/ const LLSD getValue() const; /*virtual*/ BOOL getVisible() const; /*virtual*/ void highlightText(S32 offset, S32 num_chars); + /*virtual*/ void setHighlighted(bool highlighted); /*virtual*/ void setColor(const LLColor4&); /*virtual*/ BOOL isText() const; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index da1e87fda4..15447e7e83 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8184,7 +8184,7 @@ <key>PushToTalkButton</key> <map> <key>Comment</key> - <string>Which button or keyboard key is used for push-to-talk</string> + <string>(Obsolete)Which button or keyboard key is used for push-to-talk</string> <key>Persist</key> <integer>1</integer> <key>Type</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index dde7275e8e..97e770a106 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1004,20 +1004,15 @@ bool LLAppViewer::init() gGLManager.getGLInfo(gDebugInfo); gGLManager.printGLInfoString(); - // Load Default bindings - std::string key_bindings_file = gDirUtilp->findFile("keys.xml", - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), - gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - - - if (!gViewerKeyboard.loadBindingsXML(key_bindings_file)) + // Load User's bindings + std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "keys.xml"); + if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerKeyboard.loadBindingsXML(key_bindings_file)) { - std::string key_bindings_file = gDirUtilp->findFile("keys.ini", - gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""), - gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); - if (!gViewerKeyboard.loadBindings(key_bindings_file)) + // Failed to load custom bindings, try default ones + key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "keys.xml"); + if (!gViewerKeyboard.loadBindingsXML(key_bindings_file)) { - LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL; + LL_ERRS("InitInfo") << "Unable to open default key bindings from" << key_bindings_file << LL_ENDL; } } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 6085c92f49..c0e334795a 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -222,7 +222,11 @@ BOOL LLSetKeyBindDialog::postBuild() //virtual void LLSetKeyBindDialog::onClose(bool app_quiting) { - pParent = NULL; + if (pParent) + { + pParent->onCancelKeyBind(); + pParent = NULL; + } LLModalDialog::onClose(app_quiting); } @@ -269,6 +273,7 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) if (pParent) { pParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); + pParent = NULL; } closeFloater(); return true; @@ -302,6 +307,7 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) if (pParent) { pParent->onSetKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); + pParent = NULL; } closeFloater(); return result; @@ -332,6 +338,7 @@ BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClic if (pParent) { pParent->onSetKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); + pParent = NULL; } result = TRUE; closeFloater(); @@ -360,6 +367,7 @@ void LLSetKeyBindDialog::onBlank(void* user_data) if (self->pParent) { self->pParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); + self->pParent = NULL; } self->closeFloater(); } @@ -372,6 +380,7 @@ void LLSetKeyBindDialog::onDefault(void* user_data) if (self->pParent) { self->pParent->onDefaultKeyBind(); + self->pParent = NULL; } self->closeFloater(); } @@ -2968,11 +2977,12 @@ LLPanelPreferenceControls::LLPanelPreferenceControls() mEditingIndex(-1), mEditingColumn(-1), mEditingMode(0), - mShowKeyDialog(false) + mShowKeyDialog(false), + mHighlightedCell(NULL) { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT; ++i) + for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) { - mConflictHandler[i].setLoadMode((LLKeyConflictHandler::EModes)i); + mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i); } } @@ -3000,46 +3010,34 @@ BOOL LLPanelPreferenceControls::postBuild() // Something of a workaround: cells don't handle clicks, so we catch a click, then process it on hover. BOOL LLPanelPreferenceControls::handleHover(S32 x, S32 y, MASK mask) { - /*S32 column = pControlsTable->getColumnIndexFromOffset(x); - LLScrollListItem* item = pControlsTable->hitItem(x, y); - static LLScrollListCell* last_cell = NULL; - if (item && column > 0) - { - LLScrollListCell* cell = item->getColumn(column); - if (cell) - { - cell->highlightText(0, CHAR_MAX); - if (last_cell != NULL && last_cell !=cell) - { - last_cell->highlightText(0, 0); - } - last_cell = cell; - } - }*/ - if (mShowKeyDialog) { - if (mEditingIndex > 0 && mConflictHandler[mEditingMode].canAssignControl((LLKeyConflictHandler::EControlTypes)mEditingIndex)) + mShowKeyDialog = false; + if (mEditingIndex > 0 + && mConflictHandler[mEditingMode].canAssignControl((LLKeyConflictHandler::EControlTypes)mEditingIndex)) { - mEditingColumn = pControlsTable->getColumnIndexFromOffset(x); - - if (mEditingColumn >0) + LLScrollListItem* item = pControlsTable->getFirstSelected(); // don't use pControlsTable->hitItem(x, y) dur to drift; + if (item) { - LLSetKeyBindDialog* dialog = LLFloaterReg::showTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD(), TRUE); - if (dialog) + mEditingColumn = pControlsTable->getColumnIndexFromOffset(x); + if (mEditingColumn > 0) { - /*if (mConflictHandler[mEditingMode].getLoadedMode() == LLKeyConflictHandler::MODE_GENERAL) - {*/ - dialog->setParent(this, DEFAULT_KEY_FILTER); - /*} - else + LLScrollListCell* cell = item->getColumn(mEditingColumn); + if (cell) { - dialog->setParent(this, ALLOW_KEYS | ALLOW_MASK_KEYS); - }*/ + LLSetKeyBindDialog* dialog = LLFloaterReg::showTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD(), TRUE); + if (dialog) + { + dialog->setParent(this, DEFAULT_KEY_FILTER); + cell->setHighlighted(true); + mHighlightedCell = cell; + pControlsTable->deselectAllItems(); + return TRUE; + } + } } } } - mShowKeyDialog = false; } return LLPanelPreference::handleHover(x, y, mask); } @@ -3089,7 +3087,7 @@ void LLPanelPreferenceControls::addGroupRow(const std::string &icon, S32 index) void LLPanelPreferenceControls::regenerateControls() { mEditingMode = pKeyModeBox->getValue().asInteger(); - mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::EModes)mEditingMode); + mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode); populateControlTable(); } @@ -3097,6 +3095,12 @@ void LLPanelPreferenceControls::populateControlTable() { pControlsTable->clearRows(); + if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; + } + // todo: subsections need sorting? std::string label, control_name; LLScrollListCell::Params cell_params; @@ -3189,20 +3193,50 @@ void LLPanelPreferenceControls::addSeparator() } } +void LLPanelPreferenceControls::updateTable() +{ + std::vector<LLScrollListItem*> list = pControlsTable->getAllData(); + for (S32 i = 0; i < list.size(); ++i) + { + S32 value = list[i]->getValue().asInteger(); + if (value > 0) + { + LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)value; + LLScrollListCell* cell = list[i]->getColumn(1); + cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 0)); + cell = list[i]->getColumn(2); + cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 1)); + cell = list[i]->getColumn(3); + cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 2)); + } + } + + if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; + } +} + void LLPanelPreferenceControls::apply() { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT; ++i) + for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) { if (mConflictHandler[i].hasUnsavedChanges()) { mConflictHandler[i].saveToSettings(); } } + if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; + } } void LLPanelPreferenceControls::cancel() { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT; ++i) + for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) { if (mConflictHandler[i].hasUnsavedChanges()) { @@ -3210,11 +3244,16 @@ void LLPanelPreferenceControls::cancel() } } pControlsTable->clear(); + if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; + } } void LLPanelPreferenceControls::saveSettings() { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT; ++i) + for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) { if (mConflictHandler[i].hasUnsavedChanges()) { @@ -3227,6 +3266,11 @@ void LLPanelPreferenceControls::saveSettings() { regenerateControls(); } + else if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; + } } void LLPanelPreferenceControls::resetDirtyChilds() @@ -3260,6 +3304,12 @@ void LLPanelPreferenceControls::onListCommit() // use coordinates from hover to calculate cell mEditingIndex = control; mShowKeyDialog = true; + + if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; + } } void LLPanelPreferenceControls::onModeCommit() @@ -3279,30 +3329,20 @@ void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MAS pControlsTable->deselectAllItems(); pControlsTable->selectByValue(mEditingIndex); - LLScrollListItem *item = pControlsTable->getFirstSelected(); - if (item && mEditingColumn > 0) + if ( mEditingColumn > 0) { - mConflictHandler[mEditingMode].registerControl(control, mEditingColumn - 1, click, key, mask, ignore_mask); - - LLScrollListCell *cell = item->getColumn(1); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 0)); - cell = item->getColumn(2); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 1)); - cell = item->getColumn(3); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 2)); } - populateControlTable(); + updateTable(); } void LLPanelPreferenceControls::onRestoreDefaults() { - for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT; ++i) + for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i) { mConflictHandler[mEditingMode].resetToDefaults(); } - populateControlTable(); } void LLPanelPreferenceControls::onDefaultKeyBind() @@ -3316,16 +3356,20 @@ void LLPanelPreferenceControls::onDefaultKeyBind() pControlsTable->deselectAllItems(); pControlsTable->selectByValue(mEditingIndex); - LLScrollListItem *item = pControlsTable->getFirstSelected(); - if (item) + + if (mEditingColumn > 0) { - LLScrollListCell *cell = item->getColumn(mEditingColumn); + mConflictHandler[mEditingMode].resetToDefault(control, mEditingColumn - 1); + } + updateTable(); +} - if (mEditingColumn > 0) - { - mConflictHandler[mEditingMode].resetToDefault(control, mEditingColumn - 1); - cell->setValue(mConflictHandler[mEditingMode].getControlString(control, mEditingColumn - 1)); - } +void LLPanelPreferenceControls::onCancelKeyBind() +{ + if (mHighlightedCell) + { + mHighlightedCell->setHighlighted(false); + mHighlightedCell = NULL; } } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 1ac0f076d2..513fda96df 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -46,6 +46,7 @@ class LLPanelDebug; class LLMessageSystem; class LLComboBox; class LLScrollListCtrl; +class LLScrollListCell; class LLSliderCtrl; class LLSD; class LLTextBox; @@ -313,15 +314,18 @@ public: void onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask); void onRestoreDefaults(); void onDefaultKeyBind(); + void onCancelKeyBind(); private: void addGroupRow(const std::string &icon, S32 index); void regenerateControls(); void populateControlTable(); void addSeparator(); + void updateTable(); LLScrollListCtrl* pControlsTable; LLComboBox *pKeyModeBox; + LLScrollListCell *mHighlightedCell; LLKeyConflictHandler mConflictHandler[LLKeyConflictHandler::MODE_COUNT]; S32 mEditingIndex; S32 mEditingColumn; diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index 87ea408a6a..66d420369e 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -105,8 +105,8 @@ static const std::string typetostring[LLKeyConflictHandler::CONTROL_NUM_INDICES] "control_mediacontent", "toggle_pause_media", "toggle_enable_media", - "control_voice", - "control_toggle_voice", + "voice_follow_key", + "toggle_voice", "start_chat", "start_gesture", "control_reserved", @@ -167,6 +167,8 @@ static const control_enum_t command_to_key = { "toggle_enable_media", LLKeyConflictHandler::CONTROL_ENABLE_MEDIA }, { "walk_to", LLKeyConflictHandler::CONTROL_MOVETO }, { "teleport_to", LLKeyConflictHandler::CONTROL_TELEPORTTO }, + { "toggle_voice", LLKeyConflictHandler::CONTROL_TOGGLE_VOICE }, + { "voice_follow_key", LLKeyConflictHandler::CONTROL_VOICE }, }; @@ -256,19 +258,9 @@ EMouseClickType mouse_from_string(const std::string& input) LLKeyConflictHandler::LLKeyConflictHandler() : mHasUnsavedChanges(false) { - // todo: assign conflic priorities - // todo: load from keys.xml? - - // Thise controls are meant to cause conflicts when user tries to assign same control somewhere else - /*registerTemporaryControl(CONTROL_RESERVED_MENU, CLICK_RIGHT, KEY_NONE, MASK_NONE, 0); - registerTemporaryControl(CONTROL_SHIFT_SELECT, CLICK_LEFT, KEY_NONE, MASK_SHIFT, 0); - registerTemporaryControl(CONTROL_CNTRL_SELECT, CLICK_LEFT, KEY_NONE, MASK_CONTROL, 0); - registerTemporaryControl(CONTROL_DELETE, CLICK_NONE, KEY_DELETE, MASK_NONE, 0); - - loadFromSettings();*/ } -LLKeyConflictHandler::LLKeyConflictHandler(EModes mode) +LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode) : mHasUnsavedChanges(false), mLoadMode(mode) { @@ -305,16 +297,26 @@ bool LLKeyConflictHandler::canAssignControl(EControlTypes control_type) return false; } -void LLKeyConflictHandler::registerControl(EControlTypes control_type, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) +bool LLKeyConflictHandler::registerControl(EControlTypes control_type, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) { LLKeyConflict &type_data = mControlsMap[control_type]; if (!type_data.mAssignable) { LL_ERRS() << "Error in code, user or system should not be able to change certain controls" << LL_ENDL; } - type_data.mKeyBind.replaceKeyData(mouse, key, mask, ignore_mask, index); - - mHasUnsavedChanges = true; + LLKeyData data(mouse, key, mask, ignore_mask); + if (type_data.mKeyBind.getKeyData(index) == data) + { + return true; + } + if (removeConflicts(data, type_data.mConflictMask)) + { + type_data.mKeyBind.replaceKeyData(data, index); + mHasUnsavedChanges = true; + return true; + } + // control already in use/blocked + return false; } LLKeyData LLKeyConflictHandler::getControl(EControlTypes control_type, U32 index) @@ -391,7 +393,7 @@ void LLKeyConflictHandler::loadFromSettings(const LLViewerKeyboard::KeyMode& ke } } -void LLKeyConflictHandler::loadFromSettings(const EModes &load_mode, const std::string &filename, control_map_t *destination) +void LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination) { if (filename.empty()) { @@ -442,7 +444,7 @@ void LLKeyConflictHandler::loadFromSettings(const EModes &load_mode, const std:: } } -void LLKeyConflictHandler::loadFromSettings(EModes load_mode) +void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode) { mControlsMap.clear(); mDefaultsMap.clear(); @@ -571,6 +573,11 @@ void LLKeyConflictHandler::saveToSettings() control_map_t::iterator end = mControlsMap.end(); for (; iter != end; ++iter) { + // By default xml have (had) up to 6 elements per function + // eventually it will be cleaned up and UI will only shows 3 per function, + // so make sure to cleanup. + // Also this helps in keeping file small. + iter->second.mKeyBind.trimEmpty(); U32 size = iter->second.mKeyBind.getDataCount(); for (U32 i = 0; i < size; ++i) { @@ -683,10 +690,16 @@ LLKeyData LLKeyConflictHandler::getDefaultControl(EControlTypes control_type, U3 void LLKeyConflictHandler::resetToDefault(EControlTypes control_type, U32 index) { LLKeyData data = getDefaultControl(control_type, index); - mControlsMap[control_type].setKeyData(data, index); + + if (data != mControlsMap[control_type].getKeyData(index)) + { + // reset controls that might have been switched to our current control + removeConflicts(data, mControlsMap[control_type].mConflictMask); + mControlsMap[control_type].setKeyData(data, index); + } } -void LLKeyConflictHandler::resetToDefault(EControlTypes control_type) +void LLKeyConflictHandler::resetToDefaultAndResolve(EControlTypes control_type, bool ignore_conflicts) { if (mLoadMode == MODE_GENERAL) { @@ -694,7 +707,15 @@ void LLKeyConflictHandler::resetToDefault(EControlTypes control_type) LLControlVariablePtr var = gSavedSettings.getControl(name); if (var) { - mControlsMap[control_type].mKeyBind = LLKeyBind(var->getDefault()); + LLKeyBind bind(var->getDefault()); + if (!ignore_conflicts) + { + for (S32 i = 0; i < bind.getDataCount(); ++i) + { + removeConflicts(bind.getKeyData(i), mControlsMap[control_type].mConflictMask); + } + } + mControlsMap[control_type].mKeyBind = bind; } else { @@ -706,6 +727,13 @@ void LLKeyConflictHandler::resetToDefault(EControlTypes control_type) control_map_t::iterator iter = mDefaultsMap.find(control_type); if (iter != mDefaultsMap.end()) { + if (!ignore_conflicts) + { + for (S32 i = 0; i < iter->second.mKeyBind.getDataCount(); ++i) + { + removeConflicts(iter->second.mKeyBind.getKeyData(i), mControlsMap[control_type].mConflictMask); + } + } mControlsMap[control_type].mKeyBind = iter->second.mKeyBind; } else @@ -715,7 +743,13 @@ void LLKeyConflictHandler::resetToDefault(EControlTypes control_type) } } -void LLKeyConflictHandler::resetToDefaults(EModes mode) +void LLKeyConflictHandler::resetToDefault(EControlTypes control_type) +{ + // reset specific binding without ignoring conflicts + resetToDefaultAndResolve(control_type, false); +} + +void LLKeyConflictHandler::resetToDefaults(ESourceMode mode) { if (mode == MODE_GENERAL) { @@ -735,7 +769,7 @@ void LLKeyConflictHandler::resetToDefaults(EModes mode) break; default: { - resetToDefault(type); + resetToDefaultAndResolve(type, true); break; } } @@ -785,9 +819,53 @@ void LLKeyConflictHandler::resetKeyboardBindings() gViewerKeyboard.loadBindingsXML(filename); } -void LLKeyConflictHandler::generatePlaceholders(EModes load_mode) +void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode) { + // These controls are meant to cause conflicts when user tries to assign same control somewhere else + // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks + /*registerTemporaryControl(CONTROL_RESERVED_MENU, CLICK_RIGHT, KEY_NONE, MASK_NONE, 0); + registerTemporaryControl(CONTROL_DELETE, CLICK_NONE, KEY_DELETE, MASK_NONE, 0);*/ +} +bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask) +{ + if (conlict_mask == CONFLICT_NOTHING) + { + // Can't conflict + return true; + } + std::map<EControlTypes, S32> conflict_list; + control_map_t::iterator cntrl_iter = mControlsMap.begin(); + control_map_t::iterator cntrl_end = mControlsMap.end(); + for (; cntrl_iter != cntrl_end; ++cntrl_iter) + { + S32 index = cntrl_iter->second.mKeyBind.findKeyData(data); + if (index >= 0 + && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING + && (cntrl_iter->second.mConflictMask & conlict_mask) != 0) + { + if (cntrl_iter->second.mAssignable) + { + // Potentially we can have multiple conflict flags conflicting + // including unassignable keys. + // So record the conflict and find all others before doing any changes. + // Assume that there is only one conflict per bind + conflict_list[cntrl_iter->first] = index; + } + else + { + return false; + } + } + } + + std::map<EControlTypes, S32>::iterator cnflct_iter = conflict_list.begin(); + std::map<EControlTypes, S32>::iterator cnflct_end = conflict_list.end(); + for (; cnflct_iter != cnflct_end; ++cnflct_iter) + { + mControlsMap[cnflct_iter->first].mKeyBind.resetKeyData(cnflct_iter->second); + } + return true; } void LLKeyConflictHandler::registerTemporaryControl(EControlTypes control_type, EMouseClickType mouse, KEY key, MASK mask, U32 conflict_mask) diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index b0f99e2d0c..00fbe18863 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -34,7 +34,7 @@ class LLKeyConflict { public: - LLKeyConflict() : mAssignable(true), mConflictMask(0) {} //temporary assignable, don't forget to change once all keys are recorded + 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) @@ -55,26 +55,20 @@ class LLKeyConflictHandler { public: - enum EModes // partially repeats e_keyboard_mode + enum ESourceMode // partially repeats e_keyboard_mode { MODE_FIRST_PERSON, MODE_THIRD_PERSON, MODE_EDIT, MODE_EDIT_AVATAR, MODE_SITTING, - MODE_GENERAL, + MODE_GENERAL, // for settings from saved settings MODE_COUNT }; - enum EConflictTypes // priority higherst to lowest - { - CONFLICT_LAND = 1, - CONFLICT_OBJECT = 2, - CONFLICT_TOUCH = 4, - CONFLICT_INTERACTIBLE = 8, - CONFLICT_AVATAR = 16, - CONFLICT_ANY = 511 - }; + 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 @@ -142,7 +136,7 @@ public: CONTROL_MEDIACONTENT, // Group control, for visual representation CONTROL_PAUSE_MEDIA, // Play pause CONTROL_ENABLE_MEDIA, // Play stop - CONTROL_VOICE, // Keep pressing for it to be ON + 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 @@ -158,14 +152,14 @@ public: // Note: missed selection and edition commands (would be really nice to go through selection via MB4/5 or wheel) LLKeyConflictHandler(); - LLKeyConflictHandler(EModes mode); + 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); - void registerControl(EControlTypes control_type, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts? + 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); @@ -175,7 +169,7 @@ public: // Drops any changes loads controls with ones from 'saved settings' or from xml - void loadFromSettings(EModes load_mode); + void loadFromSettings(ESourceMode load_mode); // Saves settings to 'saved settings' or to xml void saveToSettings(); @@ -190,26 +184,28 @@ public: void clear(); bool hasUnsavedChanges() { return mHasUnsavedChanges; } - void setLoadMode(EModes mode) { mLoadMode = mode; } - EModes getLoadMode() { return mLoadMode; } - // todo: conflict search + void setLoadMode(ESourceMode mode) { mLoadMode = mode; } + ESourceMode getLoadMode() { return mLoadMode; } private: - void resetToDefaults(EModes mode); + 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 EModes &load_mode, const std::string &filename, control_map_t *destination); + void loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination); void resetKeyboardBindings(); - void generatePlaceholders(EModes load_mode); //E.x. non-assignable values + 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; - EModes mLoadMode; + ESourceMode mLoadMode; }; diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index e2ab450d8c..5235914c34 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -83,8 +83,8 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask) LL_INFOS() << "LLTool left mouse down" << LL_ENDL; } // by default, didn't handle it + // AGENT_CONTROL_LBUTTON_DOWN is handled by scanMouse() and scanKey() // LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL; - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); return FALSE; } @@ -95,8 +95,8 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask) LL_INFOS() << "LLTool left mouse up" << LL_ENDL; } // by default, didn't handle it + // AGENT_CONTROL_LBUTTON_UP is handled by scanMouse() and scanKey() // LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL; - gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); return TRUE; } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 4edfd7fb39..dc9c0edc0c 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -537,13 +537,13 @@ void LLToolPie::resetSelection() mClickAction = 0; } -void LLToolPie::walkToClickedLocation() +bool LLToolPie::walkToClickedLocation() { if (gAgent.getFlying() // don't auto-navigate while flying until that works || !gAgentAvatarp || gAgentAvatarp->isSitting()) { - return; + return false; } LLPickInfo saved_pick = mPick; @@ -557,7 +557,7 @@ void LLToolPie::walkToClickedLocation() if (mPick.getObject() && mPick.getObject()->isHUDAttachment()) { mPick = saved_pick; - return; + return false; } } @@ -592,6 +592,7 @@ void LLToolPie::walkToClickedLocation() gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE); LLFirstUse::notMoving(false); showVisualContextMenuEffect(); + return true; } else { @@ -601,10 +602,12 @@ void LLToolPie::walkToClickedLocation() << ", pick object was " << mPick.mObjectID << LL_ENDL; mPick = saved_pick; + return false; } + return true; } -void LLToolPie::teleportToClickedLocation() +bool LLToolPie::teleportToClickedLocation() { LLViewerObject* objp = mHoverPick.getObject(); LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL; @@ -620,9 +623,11 @@ void LLToolPie::teleportToClickedLocation() LLVector3d pos = mHoverPick.mPosGlobal; pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot(); gAgent.teleportViaLocationLookAt(pos); + mPick = mHoverPick; + showVisualContextMenuEffect(); + return true; } - mPick = mHoverPick; - showVisualContextMenuEffect(); + return false; } // When we get object properties after left-clicking on an object diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index c1c8718f7d..60159594c9 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -67,8 +67,8 @@ public: LLViewerObject* getClickActionObject() { return mClickActionObject; } LLObjectSelection* getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; } void resetSelection(); - void walkToClickedLocation(); - void teleportToClickedLocation(); + bool walkToClickedLocation(); + bool teleportToClickedLocation(); void stopClickToWalk(); static void selectionPropertiesReceived(); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 420980ca56..9755d3444a 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -26,19 +26,21 @@ #include "llviewerprecompiledheaders.h" +#include "llviewerkeyboard.h" + #include "llappviewer.h" #include "llfloaterreg.h" -#include "llviewerkeyboard.h" #include "llmath.h" #include "llagent.h" #include "llagentcamera.h" #include "llfloaterimnearbychat.h" -#include "llviewercontrol.h" #include "llfocusmgr.h" +#include "llkeybind.h" // LLKeyData #include "llmorphview.h" #include "llmoveview.h" #include "lltoolfocus.h" #include "lltoolpie.h" +#include "llviewercontrol.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llfloatercamera.h" @@ -55,21 +57,23 @@ const F32 NUDGE_TIME = 0.25f; // in seconds const S32 NUDGE_FRAMES = 2; const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed +const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true); + struct LLKeyboardActionRegistry -: public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry> +: public LLRegistrySingleton<std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry> { LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry); }; LLViewerKeyboard gViewerKeyboard; -void agent_jump( EKeystate s ) +bool agent_jump( EKeystate s ) { static BOOL first_fly_attempt(TRUE); if (KEYSTATE_UP == s) { first_fly_attempt = TRUE; - return; + return true; } F32 time = gKeyboard->getCurKeyElapsedTime(); S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); @@ -87,12 +91,14 @@ void agent_jump( EKeystate s ) first_fly_attempt = FALSE; gAgent.moveUp(1); } + return true; } -void agent_push_down( EKeystate s ) +bool agent_push_down( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgent.moveUp(-1); + return true; } static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode) @@ -152,11 +158,11 @@ static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDo } } -void camera_move_forward( EKeystate s ); +bool camera_move_forward( EKeystate s ); -void agent_push_forward( EKeystate s ) +bool agent_push_forward( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) @@ -167,13 +173,14 @@ void agent_push_forward( EKeystate s ) { agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD); } + return true; } -void camera_move_backward( EKeystate s ); +bool camera_move_backward( EKeystate s ); -void agent_push_backward( EKeystate s ) +bool agent_push_backward( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) @@ -188,6 +195,7 @@ void agent_push_backward( EKeystate s ) { agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } + return true; } static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) @@ -208,31 +216,33 @@ static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleT } -void agent_slide_left( EKeystate s ) +bool agent_slide_left( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT); + return true; } -void agent_slide_right( EKeystate s ) +bool agent_slide_right( EKeystate s ) { - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return true; agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT); + return true; } -void camera_spin_around_cw( EKeystate s ); +bool camera_spin_around_cw( EKeystate s ); -void agent_turn_left( EKeystate s ) +bool agent_turn_left(EKeystate s) { //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) { camera_spin_around_cw(s); - return; + return true; } - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return false; if (LLToolCamera::getInstance()->mouseSteerMode()) { @@ -244,25 +254,26 @@ void agent_turn_left( EKeystate s ) { // Check temporary running. In case user released 'left' key with shift already released. agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT); - return; + return true; } F32 time = gKeyboard->getCurKeyElapsedTime(); gAgent.moveYaw( LLFloaterMove::getYawRate( time ) ); } + return true; } -void camera_spin_around_ccw( EKeystate s ); +bool camera_spin_around_ccw( EKeystate s ); -void agent_turn_right( EKeystate s ) +bool agent_turn_right( EKeystate s ) { //in free camera control mode we need to intercept keyboard events for avatar movements if (LLFloaterCamera::inFreeCameraMode()) { camera_spin_around_ccw(s); - return; + return true; } - if(gAgent.isMovementLocked()) return; + if(gAgent.isMovementLocked()) return false; if (LLToolCamera::getInstance()->mouseSteerMode()) { @@ -274,35 +285,39 @@ void agent_turn_right( EKeystate s ) { // Check temporary running. In case user released 'right' key with shift already released. agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT); - return; + return true; } F32 time = gKeyboard->getCurKeyElapsedTime(); gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) ); } + return true; } -void agent_look_up( EKeystate s ) +bool agent_look_up( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgent.movePitch(-1); //gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); + return true; } -void agent_look_down( EKeystate s ) +bool agent_look_down( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgent.movePitch(1); //gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() ); + return true; } -void agent_toggle_fly( EKeystate s ) +bool agent_toggle_fly( EKeystate s ) { // Only catch the edge if (KEYSTATE_DOWN == s ) { LLAgent::toggleFlying(); } + return true; } F32 get_orbit_rate() @@ -320,24 +335,26 @@ F32 get_orbit_rate() } } -void camera_spin_around_ccw( EKeystate s ) +bool camera_spin_around_ccw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); + return true; } -void camera_spin_around_cw( EKeystate s ) +bool camera_spin_around_cw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitRightKey( get_orbit_rate() ); + return true; } -void camera_spin_around_ccw_sitting( EKeystate s ) +bool camera_spin_around_ccw_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return true; if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { //send keystrokes, but do not change camera @@ -348,12 +365,13 @@ void camera_spin_around_ccw_sitting( EKeystate s ) //change camera but do not send keystrokes gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); } + return true; } -void camera_spin_around_cw_sitting( EKeystate s ) +bool camera_spin_around_cw_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return true; if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning()) { //send keystrokes, but do not change camera @@ -364,27 +382,30 @@ void camera_spin_around_cw_sitting( EKeystate s ) //change camera but do not send keystrokes gAgentCamera.setOrbitRightKey( get_orbit_rate() ); } + return true; } -void camera_spin_over( EKeystate s ) +bool camera_spin_over( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitUpKey( get_orbit_rate() ); + return true; } -void camera_spin_under( EKeystate s ) +bool camera_spin_under( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitDownKey( get_orbit_rate() ); + return true; } -void camera_spin_over_sitting( EKeystate s ) +bool camera_spin_over_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled()) { //send keystrokes, but do not change camera @@ -395,12 +416,13 @@ void camera_spin_over_sitting( EKeystate s ) //change camera but do not send keystrokes gAgentCamera.setOrbitUpKey( get_orbit_rate() ); } + return true; } -void camera_spin_under_sitting( EKeystate s ) +bool camera_spin_under_sitting( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled()) { //send keystrokes, but do not change camera @@ -411,26 +433,29 @@ void camera_spin_under_sitting( EKeystate s ) //change camera but do not send keystrokes gAgentCamera.setOrbitDownKey( get_orbit_rate() ); } + return true; } -void camera_move_forward( EKeystate s ) +bool camera_move_forward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitInKey( get_orbit_rate() ); + return true; } -void camera_move_backward( EKeystate s ) +bool camera_move_backward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitOutKey( get_orbit_rate() ); + return true; } -void camera_move_forward_sitting( EKeystate s ) +bool camera_move_forward_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return true; if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) { agent_push_forward(s); @@ -439,12 +464,13 @@ void camera_move_forward_sitting( EKeystate s ) { gAgentCamera.setOrbitInKey( get_orbit_rate() ); } + return true; } -void camera_move_backward_sitting( EKeystate s ) +bool camera_move_backward_sitting( EKeystate s ) { - if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return; + if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return true; if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun())) { @@ -454,139 +480,156 @@ void camera_move_backward_sitting( EKeystate s ) { gAgentCamera.setOrbitOutKey( get_orbit_rate() ); } + return true; } -void camera_pan_up( EKeystate s ) +bool camera_pan_up( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanUpKey( get_orbit_rate() ); + return true; } -void camera_pan_down( EKeystate s ) +bool camera_pan_down( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanDownKey( get_orbit_rate() ); + return true; } -void camera_pan_left( EKeystate s ) +bool camera_pan_left( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanLeftKey( get_orbit_rate() ); + return true; } -void camera_pan_right( EKeystate s ) +bool camera_pan_right( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanRightKey( get_orbit_rate() ); + return true; } -void camera_pan_in( EKeystate s ) +bool camera_pan_in( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanInKey( get_orbit_rate() ); + return true; } -void camera_pan_out( EKeystate s ) +bool camera_pan_out( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setPanOutKey( get_orbit_rate() ); + return true; } -void camera_move_forward_fast( EKeystate s ) +bool camera_move_forward_fast( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitInKey(2.5f); + return true; } -void camera_move_backward_fast( EKeystate s ) +bool camera_move_backward_fast( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gAgentCamera.unlockView(); gAgentCamera.setOrbitOutKey(2.5f); + return true; } -void edit_avatar_spin_ccw( EKeystate s ) +bool edit_avatar_spin_ccw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); //gMorphView->orbitLeft( get_orbit_rate() ); + return true; } -void edit_avatar_spin_cw( EKeystate s ) +bool edit_avatar_spin_cw( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitRightKey( get_orbit_rate() ); //gMorphView->orbitRight( get_orbit_rate() ); + return true; } -void edit_avatar_spin_over( EKeystate s ) +bool edit_avatar_spin_over( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitUpKey( get_orbit_rate() ); //gMorphView->orbitUp( get_orbit_rate() ); + return true; } -void edit_avatar_spin_under( EKeystate s ) +bool edit_avatar_spin_under( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitDownKey( get_orbit_rate() ); //gMorphView->orbitDown( get_orbit_rate() ); + return true; } -void edit_avatar_move_forward( EKeystate s ) +bool edit_avatar_move_forward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitInKey( get_orbit_rate() ); //gMorphView->orbitIn(); + return true; } -void edit_avatar_move_backward( EKeystate s ) +bool edit_avatar_move_backward( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + if( KEYSTATE_UP == s ) return true; gMorphView->setCameraDrivenByKeys( TRUE ); gAgentCamera.setOrbitOutKey( get_orbit_rate() ); //gMorphView->orbitOut(); + return true; } -void stop_moving( EKeystate s ) +bool stop_moving( EKeystate s ) { - if( KEYSTATE_DOWN != s ) return; + if( KEYSTATE_DOWN != s ) return true; // stop agent gAgent.setControlFlags(AGENT_CONTROL_STOP); // cancel autopilot gAgent.stopAutoPilot(); + return true; } -void start_chat( EKeystate s ) +bool start_chat( EKeystate s ) { if (LLAppViewer::instance()->quitRequested()) { - return; // can't talk, gotta go, kthxbye! + return true; // can't talk, gotta go, kthxbye! } - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; // start chat LLFloaterIMNearbyChat::startChat(NULL); + return true; } -void start_gesture( EKeystate s ) +bool start_gesture( EKeystate s ) { LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); if (KEYSTATE_UP == s && @@ -603,11 +646,12 @@ void start_gesture( EKeystate s ) LLFloaterIMNearbyChat::startChat(NULL); } } + return true; } -void toggle_run(EKeystate s) +bool toggle_run(EKeystate s) { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; bool run = gAgent.getAlwaysRun(); if (run) { @@ -620,11 +664,12 @@ void toggle_run(EKeystate s) gAgent.setRunning(); } gAgent.sendWalkRun(!run); + return true; } -void toggle_sit(EKeystate s) +bool toggle_sit(EKeystate s) { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; if (gAgent.isSitting()) { gAgent.standUp(); @@ -633,33 +678,75 @@ void toggle_sit(EKeystate s) { gAgent.sitDown(); } + return true; } -void toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar +bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; bool pause = LLViewerMedia::isAnyMediaPlaying(); LLViewerMedia::setAllMediaPaused(pause); + return true; } -void toggle_enable_media(EKeystate s) +bool toggle_enable_media(EKeystate s) { - if (KEYSTATE_DOWN != s) return; + if (KEYSTATE_DOWN != s) return true; bool pause = LLViewerMedia::isAnyMediaPlaying() || LLViewerMedia::isAnyMediaShowing(); LLViewerMedia::setAllMediaEnabled(!pause); + return true; } -void walk_to(EKeystate s) +bool walk_to(EKeystate s) { - LL_WARNS() << "processing " << LLSD(s).asString() << LL_ENDL; - if (KEYSTATE_DOWN != s) return; - LLToolPie::getInstance()->walkToClickedLocation(); + if (KEYSTATE_DOWN != s) return true; + return LLToolPie::getInstance()->walkToClickedLocation(); +} + +bool teleport_to(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return true; + return LLToolPie::getInstance()->teleportToClickedLocation(); +} + +bool toggle_voice(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return true; + if (!LLAgent::isActionAllowed("speak")) return false; + LLVoiceClient::getInstance()->toggleUserPTTState(); + return true; +} + +bool voice_follow_key(EKeystate s) +{ + if (KEYSTATE_DOWN == s) + { + if (!LLAgent::isActionAllowed("speak")) return false; + LLVoiceClient::getInstance()->setUserPTTState(true); + return true; + } + else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState()) + { + LLVoiceClient::getInstance()->setUserPTTState(false); + return true; + } + return false; } -void teleport_to(EKeystate s) +bool agen_control_lbutton_handle(EKeystate s) { - if (KEYSTATE_DOWN != s) return; - LLToolPie::getInstance()->teleportToClickedLocation(); + switch (s) + { + case KEYSTATE_DOWN: + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN); + break; + case KEYSTATE_UP: + gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP); + break; + default: + break; + } + return true; } #define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); @@ -709,6 +796,8 @@ REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media); REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media); REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to); REGISTER_KEYBOARD_ACTION("walk_to", walk_to); +REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice); +REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key); #undef REGISTER_KEYBOARD_ACTION LLViewerKeyboard::LLViewerKeyboard() @@ -844,7 +933,7 @@ BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const bool ignore, const std::string& function_name) { S32 index; - typedef boost::function<void(EKeystate)> function_t; + typedef boost::function<bool(EKeystate)> function_t; function_t function = NULL; std::string name; @@ -935,7 +1024,7 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c BOOL LLViewerKeyboard::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const bool ignore, const std::string& function_name) { S32 index; - typedef boost::function<void(EKeystate)> function_t; + typedef boost::function<bool(EKeystate)> function_t; function_t function = NULL; function_t* result = LLKeyboardActionRegistry::getValue(function_name); @@ -1105,102 +1194,6 @@ S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, return binding_count; } -S32 LLViewerKeyboard::loadBindings(const std::string& filename) -{ - LLFILE *fp; - const S32 BUFFER_SIZE = 2048; - char buffer[BUFFER_SIZE]; /* Flawfinder: ignore */ - // *NOTE: This buffer size is hard coded into scanf() below. - char mode_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - char key_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - char mask_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - char function_string[MAX_STRING] = ""; /* Flawfinder: ignore */ - S32 mode = MODE_THIRD_PERSON; - KEY key = 0; - MASK mask = 0; - S32 tokens_read; - S32 binding_count = 0; - S32 line_count = 0; - - if(filename.empty()) - { - LL_ERRS() << " No filename specified" << LL_ENDL; - return 0; - } - - fp = LLFile::fopen(filename, "r"); - - if (!fp) - { - return 0; - } - - - while (!feof(fp)) - { - line_count++; - if (!fgets(buffer, BUFFER_SIZE, fp)) - break; - - // skip over comments, blank lines - if (buffer[0] == '#' || buffer[0] == '\n') continue; - - // grab the binding strings - tokens_read = sscanf( /* Flawfinder: ignore */ - buffer, - "%254s %254s %254s %254s", - mode_string, - key_string, - mask_string, - function_string); - - if (tokens_read == EOF) - { - LL_INFOS() << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << LL_ENDL; - fclose(fp); - return 0; - } - else if (tokens_read < 4) - { - LL_INFOS() << "Can't read line " << line_count << " of key binding file " << filename << LL_ENDL; - continue; - } - - // convert mode - if (!modeFromString(mode_string, &mode)) - { - LL_INFOS() << "Unknown mode on line " << line_count << " of key binding file " << filename << LL_ENDL; - LL_INFOS() << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << LL_ENDL; - continue; - } - - // convert key - if (!LLKeyboard::keyFromString(key_string, &key)) - { - LL_INFOS() << "Can't interpret key on line " << line_count << " of key binding file " << filename << LL_ENDL; - continue; - } - - // convert mask - if (!LLKeyboard::maskFromString(mask_string, &mask)) - { - LL_INFOS() << "Can't interpret mask on line " << line_count << " of key binding file " << filename << LL_ENDL; - continue; - } - - // bind key - if (bindKey(mode, key, mask, false, function_string)) - { - binding_count++; - } - } - - fclose(fp); - - return binding_count; -} - - EKeyboardMode LLViewerKeyboard::getMode() const { if ( gAgentCamera.cameraMouselook() ) @@ -1236,27 +1229,26 @@ bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, { if (binding[i].mMask == mask) { + bool res = false; if (key_down && !repeat) { // ...key went down this frame, call function - binding[i].mFunction( KEYSTATE_DOWN ); + res = binding[i].mFunction( KEYSTATE_DOWN ); return true; } else if (key_up) { // ...key went down this frame, call function - binding[i].mFunction( KEYSTATE_UP ); - return true; + res = binding[i].mFunction( KEYSTATE_UP ); } else if (key_level) { // ...key held down from previous frame // Not windows, just call the function. - binding[i].mFunction( KEYSTATE_LEVEL ); - return true; + res = binding[i].mFunction( KEYSTATE_LEVEL ); }//if // Key+Mask combinations are supposed to be unique, so we won't find anything else - return false; + return res; }//if }//if }//for @@ -1264,7 +1256,7 @@ bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, } // Called from scanKeyboard. -void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const +bool LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const { if (LLApp::isExiting()) { @@ -1277,17 +1269,31 @@ void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_lev if (mKeyHandledByUI[key]) { - return; + return false; } // don't process key down on repeated keys BOOL repeat = gKeyboard->getKeyRepeated(key); - if (scanKey(mKeyBindings[mode], mKeyBindingCount[mode], key, mask, key_down, key_up, key_level, repeat)) + bool res = scanKey(mKeyBindings[mode], mKeyBindingCount[mode], key, mask, key_down, key_up, key_level, repeat); + if (!res) { // Nothing found, try ignore list - scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); + res = scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); } + + if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask)) + { + if (key_down && !repeat) + { + res = agen_control_lbutton_handle(KEYSTATE_DOWN); + } + if (key_up) + { + res = agen_control_lbutton_handle(KEYSTATE_UP); + } + } + return res; } BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) @@ -1368,23 +1374,30 @@ bool LLViewerKeyboard::scanMouse(const LLMouseBinding *binding, S32 binding_coun { if (binding[i].mMouse == mouse && binding[i].mMask == mask) { + bool res = false; switch (state) { case MOUSE_STATE_DOWN: + res = binding[i].mFunction(KEYSTATE_DOWN); + break; case MOUSE_STATE_CLICK: - binding[i].mFunction(KEYSTATE_DOWN); + // Button went down and up in scope of single frame + // might not work best with some functions, + // but some function need specific states specifically + res = binding[i].mFunction(KEYSTATE_DOWN); + res |= binding[i].mFunction(KEYSTATE_UP); break; case MOUSE_STATE_LEVEL: - binding[i].mFunction(KEYSTATE_LEVEL); + res = binding[i].mFunction(KEYSTATE_LEVEL); break; case MOUSE_STATE_UP: - binding[i].mFunction(KEYSTATE_UP); + res = binding[i].mFunction(KEYSTATE_UP); break; default: break; } // Key+Mask combinations are supposed to be unique, no need to continue - return true; + return res; } } return false; @@ -1401,6 +1414,30 @@ bool LLViewerKeyboard::scanMouse(EMouseClickType click, EMouseState state) const { res = scanMouse(mMouseIgnoreMask[mode], mMouseIgnoreMaskCount[mode], click, MASK_NONE, state); } + // no user defined actions found or those actions can't handle the key/button, handle control if nessesary + if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask)) + { + switch (state) + { + case MOUSE_STATE_DOWN: + agen_control_lbutton_handle(KEYSTATE_DOWN); + res = true; + break; + case MOUSE_STATE_CLICK: + // might not work best with some functions, + // but some function need specific states too specifically + agen_control_lbutton_handle(KEYSTATE_DOWN); + agen_control_lbutton_handle(KEYSTATE_UP); + res = true; + break; + case MOUSE_STATE_UP: + agen_control_lbutton_handle(KEYSTATE_UP); + res = true; + break; + default: + break; + } + } return res; } @@ -1413,7 +1450,7 @@ void LLViewerKeyboard::scanMouse() scanMouse((EMouseClickType)i, mMouseLevel[i]); if (mMouseLevel[i] == MOUSE_STATE_DOWN) { - // mouse doesn't support 'continued' state like keyboard does, so after handling, switch to LEVEL + // mouse doesn't support 'continued' state, so after handling, switch to LEVEL mMouseLevel[i] = MOUSE_STATE_LEVEL; } else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK) diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index 10b16e5fa0..02fa21d4f2 100644 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -115,14 +115,16 @@ public: 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; + bool 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); @@ -163,6 +165,10 @@ private: // 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 + + // TODO: at some point it is better to remake this, especially keyaboard part + // would be much better to send to functions actual state of the button than + // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown) S32 mKeyBindingCount[MODE_COUNT]; S32 mKeyIgnoreMaskCount[MODE_COUNT]; S32 mMouseBindingCount[MODE_COUNT]; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index bd5370f07f..caf7a8a65a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -918,8 +918,6 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m x = ll_round((F32)x / mDisplayScale.mV[VX]); y = ll_round((F32)y / mDisplayScale.mV[VY]); - LLVoiceClient::getInstance()->updateMouseState(clicktype, mask, down); - // only send mouse clicks to UI if UI is visible if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { @@ -1437,9 +1435,6 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) { - // Let the voice chat code check for its PTT key. Note that this never affects event processing. - LLVoiceClient::getInstance()->keyDown(key, mask); - if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) { gAgent.clearAFK(); @@ -1464,9 +1459,6 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) { - // Let the voice chat code check for its PTT key. Note that this never affects event processing. - LLVoiceClient::getInstance()->keyUp(key, mask); - // Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance(); if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp) diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index fcca081647..041f617ae5 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -199,8 +199,6 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion() void LLVoiceClient::updateSettings() { setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled")); - std::string keyString = gSavedSettings.getString("PushToTalkButton"); - setPTTKey(keyString); setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle")); mDisableMic = gSavedSettings.getBOOL("VoiceDisableMic"); @@ -636,32 +634,6 @@ bool LLVoiceClient::getPTTIsToggle() return mPTTIsToggle; } -void LLVoiceClient::setPTTKey(std::string &key) -{ - // Value is stored as text for readability - if(key == "MiddleMouse") - { - mPTTMouseButton = CLICK_MIDDLE; - } - else if(key == "MouseButton4") - { - mPTTMouseButton = CLICK_BUTTON4; - } - else if (key == "MouseButton5") - { - mPTTMouseButton = CLICK_BUTTON5; - } - else - { - mPTTMouseButton = 0; - if(!LLKeyboard::keyFromString(key, &mPTTKey)) - { - // If the call failed, don't match any key. - key = KEY_NONE; - } - } -} - void LLVoiceClient::inputUserControlState(bool down) { if(mPTTIsToggle) @@ -682,48 +654,6 @@ void LLVoiceClient::toggleUserPTTState(void) setUserPTTState(!getUserPTTState()); } -void LLVoiceClient::keyDown(KEY key, MASK mask) -{ - if (gKeyboard->getKeyRepeated(key)) - { - // ignore auto-repeat keys - return; - } - - // - /*static LLCachedControl<LLSD> key_bind(gSavedSettings, "control_toggle_voice"); - LLKeyBind bind(key_bind); - if (LLAgent::isActionAllowed("speak") && bind().canHandleKey(key, mask)) - { - bool down = gKeyboard->getKeyDown(mPTTKey); - if (down) - { - inputUserControlState(down); - } - }*/ - -} -void LLVoiceClient::keyUp(KEY key, MASK mask) -{ - /*static LLCachedControl<LLKeyBind> key_bind(gSavedSettings, "control_toggle_voice"); - if (key_bind().canHandleKey(key, mask)) - { - bool down = gKeyboard->getKeyDown(mPTTKey); - if (!down) - { - inputUserControlState(down); - } - }*/ -} -void LLVoiceClient::updateMouseState(S32 click, MASK mask, bool down) -{ - /*static LLCachedControl<LLKeyBind> mouse_bind(gSavedSettings, "control_toggle_voice"); - if (mouse_bind().canHandleMouse((EMouseClickType)click, mask)) - { - inputUserControlState(down); - }*/ -} - //------------------------------------------- // nearby speaker accessors diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index e3285b0c9b..52f4ff13b5 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -409,16 +409,10 @@ public: void setUsePTT(bool usePTT); void setPTTIsToggle(bool PTTIsToggle); bool getPTTIsToggle(); - void setPTTKey(std::string &key); - + void updateMicMuteLogic(); - + BOOL lipSyncEnabled(); - - // PTT key triggering - void keyDown(KEY key, MASK mask); - void keyUp(KEY key, MASK mask); - void updateMouseState(S32 click, MASK mask, bool down); boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } diff --git a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml index 0c652845f0..ac4be34be2 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml @@ -274,10 +274,6 @@ label="Sitting" name="sitting" value="4"/> - <combo_box.item - label="General" - name="general" - value="5"/> </combo_box> <button @@ -301,6 +297,7 @@ right="-3" can_sort="false" multi_select="false" + bg_selected_color="Transparent" name="controls_list"> <scroll_list.columns relative_width="0.34" |