diff options
| author | andreykproductengine <andreykproductengine@lindenlab.com> | 2019-09-26 22:28:18 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2020-06-23 14:48:03 +0300 | 
| commit | 2532a2ee9ee9003e2c6b72f8da19979a9e3dd2f6 (patch) | |
| tree | 73205ed8bedfc5855082205ee5334d7e06f45d80 /indra | |
| parent | 4ae2165c4516a74012d30610b4c53de6d3ccaf90 (diff) | |
SL-6109 Conflict resolution
Diffstat (limited to 'indra')
| -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 e8f01f7a60..d0cd4e2b39 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8274,7 +8274,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 1cb3c1af31..06deed9e58 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1002,20 +1002,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 0af6249351..4852a9d93e 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();  } @@ -2917,11 +2926,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);      }  } @@ -2949,46 +2959,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);  } @@ -3038,7 +3036,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();  } @@ -3046,6 +3044,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; @@ -3138,20 +3142,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())          { @@ -3159,11 +3193,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())          { @@ -3176,6 +3215,11 @@ void LLPanelPreferenceControls::saveSettings()      {          regenerateControls();      } +    else if (mHighlightedCell) +    { +        mHighlightedCell->setHighlighted(false); +        mHighlightedCell = NULL; +    }  }  void LLPanelPreferenceControls::resetDirtyChilds() @@ -3209,6 +3253,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() @@ -3228,30 +3278,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() @@ -3265,16 +3305,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 dbf493b60d..9178927e74 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; @@ -314,15 +315,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 35b4306e1d..1b54402221 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 abc7346616..2647abc74c 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 @@ -349,12 +366,13 @@ void camera_spin_around_ccw_sitting( EKeystate s )  		gAgentCamera.unlockView();  		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 @@ -366,27 +384,30 @@ void camera_spin_around_cw_sitting( EKeystate s )  		gAgentCamera.unlockView();  		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 @@ -397,12 +418,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 @@ -413,26 +435,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); @@ -441,12 +466,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()))  	{ @@ -456,139 +482,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 && @@ -605,11 +648,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)      { @@ -622,11 +666,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(); @@ -635,33 +680,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); @@ -711,6 +798,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() @@ -846,7 +935,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; @@ -937,7 +1026,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); @@ -1107,102 +1196,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() ) @@ -1238,27 +1231,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 @@ -1266,7 +1258,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())  	{ @@ -1279,17 +1271,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) @@ -1370,23 +1376,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; @@ -1403,6 +1416,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;  } @@ -1415,7 +1452,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 af8347688d..77ae85e7f6 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -934,8 +934,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))  	{	 @@ -1453,9 +1451,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(); @@ -1480,9 +1475,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 f8588156c1..fca8de7410 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -200,8 +200,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"); @@ -637,32 +635,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) @@ -683,48 +655,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 12916ab71b..cecaac7f85 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -408,16 +408,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" | 
