From b8c5ae8d8fcf9219112c4ab48233615732737e44 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 3 Oct 2019 19:46:12 +0300 Subject: SL-6109 Better menu accelerator support and slight reorganization --- indra/llui/llmenugl.cpp | 21 +++ indra/llui/llmenugl.h | 2 + indra/newview/CMakeLists.txt | 2 + indra/newview/llfloaterpreference.cpp | 306 +------------------------------ indra/newview/llfloaterpreference.h | 5 +- indra/newview/llkeyconflict.cpp | 21 +++ indra/newview/llkeyconflict.h | 2 + indra/newview/llpanelpresetspulldown.cpp | 1 - indra/newview/llsetkeybinddialog.cpp | 298 ++++++++++++++++++++++++++++++ indra/newview/llsetkeybinddialog.h | 88 +++++++++ indra/newview/llstartup.cpp | 1 - 11 files changed, 440 insertions(+), 307 deletions(-) create mode 100644 indra/newview/llsetkeybinddialog.cpp create mode 100644 indra/newview/llsetkeybinddialog.h diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index e6a3de281e..986f3362b7 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3514,6 +3514,27 @@ S32 LLMenuBarGL::getRightmostMenuEdge() return (*item_iter)->getRect().mRight; } +bool LLMenuBarGL::hasAccelerator(const KEY &key, const MASK &mask) const +{ + if (key == KEY_NONE) + { + return false; + } + + LLMenuKeyboardBinding *accelerator = NULL; + std::list::const_iterator list_it; + for (list_it = mAccelerators.begin(); list_it != mAccelerators.end(); ++list_it) + { + accelerator = *list_it; + if ((accelerator->mKey == key) && (accelerator->mMask == (mask & MASK_NORMALKEYS))) + { + return true; + } + } + + return false; +} + // add a vertical separator to this menu BOOL LLMenuBarGL::addSeparator() { diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 3a6b849e73..0653864892 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -792,6 +792,8 @@ public: void resetMenuTrigger() { mAltKeyTrigger = FALSE; } + bool hasAccelerator(const KEY &key, const MASK &mask) const; + private: // add a menu - this will create a drop down menu. virtual BOOL appendMenu( LLMenuGL* menu ); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a35d0cba50..8345d5c445 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -551,6 +551,7 @@ set(viewer_SOURCE_FILES llsecapi.cpp llsechandler_basic.cpp llselectmgr.cpp + llsetkeybinddialog.cpp llshareavatarhandler.cpp llsidepanelappearance.cpp llsidepanelinventory.cpp @@ -1172,6 +1173,7 @@ set(viewer_HEADER_FILES llsecapi.h llsechandler_basic.h llselectmgr.h + llsetkeybinddialog.h llsidepanelappearance.h llsidepanelinventory.h llsidepanelinventorysubpanel.h diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 2354be25e9..6ee1bbee1a 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -43,7 +43,6 @@ #include "llcombobox.h" #include "llcommandhandler.h" #include "lldirpicker.h" -#include "lldrawfrustum.h" #include "lleventtimer.h" #include "llfeaturemanager.h" #include "llfocusmgr.h" @@ -161,306 +160,6 @@ struct LabelTable : public LLInitParam::Block {} }; -// Filters for LLSetKeyBindDialog -static const U32 ALLOW_MOUSE = 1; -static const U32 ALLOW_MASK_MOUSE = 2; -static const U32 ALLOW_KEYS = 4; //keyboard -static const U32 ALLOW_MASK_KEYS = 8; -static const U32 ALLOW_MASKS = 16; -static const U32 CAN_IGNORE_MASKS = 32; // For example W (aka Forward) should work regardless of SHIFT being pressed -static const U32 DEFAULT_KEY_FILTER = ALLOW_MOUSE | ALLOW_MASK_MOUSE | ALLOW_KEYS | ALLOW_MASK_KEYS | CAN_IGNORE_MASKS; - -class LLSetKeyBindDialog : public LLModalDialog, public LLDrawFrustum -{ -public: - LLSetKeyBindDialog(const LLSD& key); - ~LLSetKeyBindDialog(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onClose(bool app_quiting); - /*virtual*/ void draw(); - - void setParent(LLPanelPreferenceControls* parent, U32 key_mask = DEFAULT_KEY_FILTER); - - BOOL handleKeyHere(KEY key, MASK mask); - BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); - static void onCancel(void* user_data); - static void onBlank(void* user_data); - static void onDefault(void* user_data); - static void onClickTimeout(void* user_data, MASK mask); - - class Updater; - -private: - void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore); - LLPanelPreferenceControls* pParent; - LLCheckBoxCtrl* pCheckBox; - - U32 mKeyFilterMask; - Updater *pUpdater; -}; - -class LLSetKeyBindDialog::Updater : public LLEventTimer -{ -public: - - typedef boost::function callback_t; - - Updater(callback_t cb, F32 period, MASK mask) - :LLEventTimer(period), - mMask(mask), - mCallback(cb) - { - mEventTimer.start(); - } - - virtual ~Updater(){} - -protected: - BOOL tick() - { - mCallback(mMask); - // Deletes itseft after execution - return TRUE; - } - -private: - MASK mMask; - callback_t mCallback; -}; - -LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key) - : LLModalDialog(key), - pParent(NULL), - mKeyFilterMask(DEFAULT_KEY_FILTER), - pUpdater(NULL) -{ -} - -LLSetKeyBindDialog::~LLSetKeyBindDialog() -{ -} - -//virtual -BOOL LLSetKeyBindDialog::postBuild() -{ - childSetAction("SetEmpty", onBlank, this); - childSetAction("Default", onDefault, this); - childSetAction("Cancel", onCancel, this); - getChild("Cancel")->setFocus(TRUE); - - pCheckBox = getChild("ignore_masks"); - - gFocusMgr.setKeystrokesOnly(TRUE); - - return TRUE; -} - -//virtual -void LLSetKeyBindDialog::onClose(bool app_quiting) -{ - if (pParent) - { - pParent->onCancelKeyBind(); - pParent = NULL; - } - if (pUpdater) - { - // Doubleclick timer has't fired, delete it - delete pUpdater; - pUpdater = NULL; - } - LLModalDialog::onClose(app_quiting); -} - -//virtual -void LLSetKeyBindDialog::draw() -{ - LLRect local_rect; - drawFrustum(local_rect, this, (LLView*)getDragHandle(), hasFocus()); - LLModalDialog::draw(); -} - -void LLSetKeyBindDialog::setParent(LLPanelPreferenceControls* parent, U32 key_mask) -{ - pParent = parent; - setFrustumOrigin(parent); - mKeyFilterMask = key_mask; - - LLTextBase *text_ctrl = getChild("descritption"); - - std::string input; - if ((key_mask & ALLOW_MOUSE) != 0) - { - input = getString("mouse"); - } - if ((key_mask & ALLOW_KEYS) != 0) - { - if (!input.empty()) - { - input += ", "; - } - input += getString("keyboard"); - } - text_ctrl->setTextArg("[INPUT]", input); - - bool can_ignore_masks = (key_mask & CAN_IGNORE_MASKS) != 0; - pCheckBox->setVisible(can_ignore_masks); - pCheckBox->setValue(false); -} - -BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) -{ - if ((key == 'Q' && mask == MASK_CONTROL) - || key == KEY_ESCAPE) - { - closeFloater(); - return TRUE; - } - - if (key == KEY_DELETE) - { - setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); - closeFloater(); - return FALSE; - } - - // forbidden keys - if (key == KEY_NONE - || key == KEY_RETURN - || key == KEY_BACKSPACE) - { - return FALSE; - } - - if ((mKeyFilterMask & ALLOW_MASKS) == 0 - && (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT)) - { - // mask by themself are not allowed - return FALSE; - } - else if ((mKeyFilterMask & ALLOW_KEYS) == 0) - { - // basic keys not allowed - return FALSE; - } - else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0) - { - // masked keys not allowed - return FALSE; - } - - setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); - closeFloater(); - return TRUE; -} - -BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) -{ - BOOL result = FALSE; - if (!pParent) - { - // we already processed 'down' event, this is 'up', consume - closeFloater(); - result = TRUE; - } - if (!result && clicktype == CLICK_LEFT) - { - // try handling buttons first - if (down) - { - result = LLView::handleMouseDown(x, y, mask); - } - else - { - result = LLView::handleMouseUp(x, y, mask); - } - if (result) - { - setFocus(TRUE); - gFocusMgr.setKeystrokesOnly(TRUE); - } - // ignore selection related combinations - else if (down && (mask & (MASK_SHIFT | MASK_CONTROL)) == 0) - { - // this can be a double click, wait a bit; - if (!pUpdater) - { - // Note: default doubleclick time is 500ms, but can stretch up to 5s - pUpdater = new Updater(boost::bind(&onClickTimeout, this, _1), 0.7f, mask); - result = TRUE; - } - } - } - - if (!result - && (clicktype != CLICK_LEFT) // subcases were handled above - && ((mKeyFilterMask & ALLOW_MOUSE) != 0) - && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported - && ((mKeyFilterMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) // reserved for selection - { - setKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); - result = TRUE; - if (!down) - { - // wait for 'up' event before closing - // alternative: set pUpdater - closeFloater(); - } - } - - return result; -} - -//static -void LLSetKeyBindDialog::onCancel(void* user_data) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - self->closeFloater(); -} - -//static -void LLSetKeyBindDialog::onBlank(void* user_data) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - // tmp needs 'no key' button - self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); - self->closeFloater(); -} - -//static -void LLSetKeyBindDialog::onDefault(void* user_data) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - if (self->pParent) - { - self->pParent->onDefaultKeyBind(); - self->pParent = NULL; - } - self->closeFloater(); -} - -//static -void LLSetKeyBindDialog::onClickTimeout(void* user_data, MASK mask) -{ - LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; - - // timer will delete itself after timeout - self->pUpdater = NULL; - - self->setKeyBind(CLICK_LEFT, KEY_NONE, mask, self->pCheckBox->getValue().asBoolean()); - self->closeFloater(); -} - -void LLSetKeyBindDialog::setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore) -{ - if (pParent) - { - pParent->onSetKeyBind(click, key, mask, ignore); - pParent = NULL; - } -} - // global functions @@ -3248,11 +2947,11 @@ void LLPanelPreferenceControls::onModeCommit() } // todo: copy onSetKeyBind to interface and inherit from interface -void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask) +bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask) { if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl)) { - return; + return true; } if ( mEditingColumn > 0) @@ -3261,6 +2960,7 @@ void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MAS } updateTable(); + return true; } void LLPanelPreferenceControls::onRestoreDefaults() diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index c1f58d290b..9734ea30a2 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -37,6 +37,7 @@ #include "llavatarpropertiesprocessor.h" #include "llconversationlog.h" #include "llsearcheditor.h" +#include "llsetkeybinddialog.h" #include "llkeyconflict.h" class LLConversationLogObserver; @@ -285,7 +286,7 @@ private: LOG_CLASS(LLPanelPreferenceGraphics); }; -class LLPanelPreferenceControls : public LLPanelPreference +class LLPanelPreferenceControls : public LLPanelPreference, public LLKeyBindResponderInterface { LOG_CLASS(LLPanelPreferenceControls); public: @@ -301,7 +302,7 @@ public: void onListCommit(); void onModeCommit(); - void onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask); + bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask); void onRestoreDefaults(); void onDefaultKeyBind(); void onCancelKeyBind(); diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index 01230ea26a..bad4e4a2d8 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -38,6 +38,7 @@ #include "llkeyboard.h" #include "llviewercontrol.h" #include "llviewerinput.h" +#include "llviewermenu.h" #include "llxuiparser.h" //#include "llstring.h" @@ -170,6 +171,22 @@ bool LLKeyConflictHandler::canAssignControl(const std::string &control_name) return true; } +// static +bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask) +{ + return gMenuBarView->hasAccelerator(key, mask) || gLoginMenuBarView->hasAccelerator(key, mask); +} + +// static +bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data) +{ + if (data.mMouse != CLICK_NONE) + { + return false; + } + return gMenuBarView->hasAccelerator(data.mKey, data.mMask) || gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask); +} + bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) { if (control_name.empty()) @@ -186,6 +203,10 @@ bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 { return true; } + if (isReservedByMenu(data)) + { + return false; + } if (removeConflicts(data, type_data.mConflictMask)) { type_data.mKeyBind.replaceKeyData(data, index); diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index e339264aaa..5c3b860ec6 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -80,6 +80,8 @@ public: bool canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask); bool canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask); //Just for convinience bool canAssignControl(const std::string &control_name); + static bool isReservedByMenu(const KEY &key, const MASK &mask); + static bool isReservedByMenu(const LLKeyData &data); bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts? LLKeyData getControl(const std::string &control_name, U32 data_index); diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp index 9b4dc5474a..1a49cbc250 100644 --- a/indra/newview/llpanelpresetspulldown.cpp +++ b/indra/newview/llpanelpresetspulldown.cpp @@ -34,7 +34,6 @@ #include "llbutton.h" #include "lltabcontainer.h" #include "llfloaterreg.h" -#include "llfloaterpreference.h" #include "llpresetsmanager.h" #include "llsliderctrl.h" #include "llscrolllistctrl.h" diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp new file mode 100644 index 0000000000..0ad71cb372 --- /dev/null +++ b/indra/newview/llsetkeybinddialog.cpp @@ -0,0 +1,298 @@ +/** + * @file llsetkeybinddialog.cpp + * @brief LLSetKeyBindDialog class implementation. + * + * $LicenseInfo:firstyear=2019&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llsetkeybinddialog.h" + +//#include "llkeyboard.h" + +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "lleventtimer.h" +#include "llfocusmgr.h" + +class LLSetKeyBindDialog::Updater : public LLEventTimer +{ +public: + + typedef boost::function callback_t; + + Updater(callback_t cb, F32 period, MASK mask) + :LLEventTimer(period), + mMask(mask), + mCallback(cb) + { + mEventTimer.start(); + } + + virtual ~Updater(){} + +protected: + BOOL tick() + { + mCallback(mMask); + // Deletes itseft after execution + return TRUE; + } + +private: + MASK mMask; + callback_t mCallback; +}; + +LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key) + : LLModalDialog(key), + pParent(NULL), + mKeyFilterMask(DEFAULT_KEY_FILTER), + pUpdater(NULL) +{ +} + +LLSetKeyBindDialog::~LLSetKeyBindDialog() +{ +} + +//virtual +BOOL LLSetKeyBindDialog::postBuild() +{ + childSetAction("SetEmpty", onBlank, this); + childSetAction("Default", onDefault, this); + childSetAction("Cancel", onCancel, this); + getChild("Cancel")->setFocus(TRUE); + + pCheckBox = getChild("ignore_masks"); + + gFocusMgr.setKeystrokesOnly(TRUE); + + return TRUE; +} + +//virtual +void LLSetKeyBindDialog::onClose(bool app_quiting) +{ + if (pParent) + { + pParent->onCancelKeyBind(); + pParent = NULL; + } + if (pUpdater) + { + // Doubleclick timer has't fired, delete it + delete pUpdater; + pUpdater = NULL; + } + LLModalDialog::onClose(app_quiting); +} + +//virtual +void LLSetKeyBindDialog::draw() +{ + LLRect local_rect; + drawFrustum(local_rect, this, (LLView*)getDragHandle(), hasFocus()); + LLModalDialog::draw(); +} + +void LLSetKeyBindDialog::setParent(LLPanelPreferenceControls* parent, U32 key_mask) +{ + pParent = parent; + setFrustumOrigin(parent); + mKeyFilterMask = key_mask; + + LLTextBase *text_ctrl = getChild("descritption"); + + std::string input; + if ((key_mask & ALLOW_MOUSE) != 0) + { + input = getString("mouse"); + } + if ((key_mask & ALLOW_KEYS) != 0) + { + if (!input.empty()) + { + input += ", "; + } + input += getString("keyboard"); + } + text_ctrl->setTextArg("[INPUT]", input); + + bool can_ignore_masks = (key_mask & CAN_IGNORE_MASKS) != 0; + pCheckBox->setVisible(can_ignore_masks); + pCheckBox->setValue(false); +} + +BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) +{ + if ((key == 'Q' && mask == MASK_CONTROL) + || key == KEY_ESCAPE) + { + closeFloater(); + return TRUE; + } + + if (key == KEY_DELETE) + { + setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); + closeFloater(); + return FALSE; + } + + // forbidden keys + if (key == KEY_NONE + || key == KEY_RETURN + || key == KEY_BACKSPACE) + { + return FALSE; + } + + if ((mKeyFilterMask & ALLOW_MASKS) == 0 + && (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT)) + { + // mask by themself are not allowed + return FALSE; + } + else if ((mKeyFilterMask & ALLOW_KEYS) == 0) + { + // basic keys not allowed + return FALSE; + } + else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0) + { + // masked keys not allowed + return FALSE; + } + + setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); + closeFloater(); + return TRUE; +} + +BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) +{ + BOOL result = FALSE; + if (!pParent) + { + // we already processed 'down' event, this is 'up', consume + closeFloater(); + result = TRUE; + } + if (!result && clicktype == CLICK_LEFT) + { + // try handling buttons first + if (down) + { + result = LLView::handleMouseDown(x, y, mask); + } + else + { + result = LLView::handleMouseUp(x, y, mask); + } + if (result) + { + setFocus(TRUE); + gFocusMgr.setKeystrokesOnly(TRUE); + } + // ignore selection related combinations + else if (down && (mask & (MASK_SHIFT | MASK_CONTROL)) == 0) + { + // this can be a double click, wait a bit; + if (!pUpdater) + { + // Note: default doubleclick time is 500ms, but can stretch up to 5s + pUpdater = new Updater(boost::bind(&onClickTimeout, this, _1), 0.7f, mask); + result = TRUE; + } + } + } + + if (!result + && (clicktype != CLICK_LEFT) // subcases were handled above + && ((mKeyFilterMask & ALLOW_MOUSE) != 0) + && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported + && ((mKeyFilterMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) // reserved for selection + { + setKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); + result = TRUE; + if (!down) + { + // wait for 'up' event before closing + // alternative: set pUpdater + closeFloater(); + } + } + + return result; +} + +//static +void LLSetKeyBindDialog::onCancel(void* user_data) +{ + LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; + self->closeFloater(); +} + +//static +void LLSetKeyBindDialog::onBlank(void* user_data) +{ + LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; + // tmp needs 'no key' button + self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); + self->closeFloater(); +} + +//static +void LLSetKeyBindDialog::onDefault(void* user_data) +{ + LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; + if (self->pParent) + { + self->pParent->onDefaultKeyBind(); + self->pParent = NULL; + } + self->closeFloater(); +} + +//static +void LLSetKeyBindDialog::onClickTimeout(void* user_data, MASK mask) +{ + LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; + + // timer will delete itself after timeout + self->pUpdater = NULL; + + self->setKeyBind(CLICK_LEFT, KEY_NONE, mask, self->pCheckBox->getValue().asBoolean()); + self->closeFloater(); +} + +void LLSetKeyBindDialog::setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore) +{ + if (pParent) + { + pParent->onSetKeyBind(click, key, mask, ignore); + pParent = NULL; + } +} + diff --git a/indra/newview/llsetkeybinddialog.h b/indra/newview/llsetkeybinddialog.h new file mode 100644 index 0000000000..fb3b2a2269 --- /dev/null +++ b/indra/newview/llsetkeybinddialog.h @@ -0,0 +1,88 @@ +/** + * @file llsetkeybinddialog.h + * @brief LLSetKeyBindDialog class definition + * + * $LicenseInfo:firstyear=2019&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef LL_LLSETKEYBINDDIALOG_H +#define LL_LLSETKEYBINDDIALOG_H + +#include "llmodaldialog.h" +#include "lldrawfrustum.h" + +class LLCheckBoxCtrl; + +// Filters for LLSetKeyBindDialog +static const U32 ALLOW_MOUSE = 1; +static const U32 ALLOW_MASK_MOUSE = 2; +static const U32 ALLOW_KEYS = 4; //keyboard +static const U32 ALLOW_MASK_KEYS = 8; +static const U32 ALLOW_MASKS = 16; +static const U32 CAN_IGNORE_MASKS = 32; // For example W (aka Forward) should work regardless of SHIFT being pressed +static const U32 DEFAULT_KEY_FILTER = ALLOW_MOUSE | ALLOW_MASK_MOUSE | ALLOW_KEYS | ALLOW_MASK_KEYS | CAN_IGNORE_MASKS; + + +class LLKeyBindResponderInterface +{ +public: + virtual ~LLKeyBindResponderInterface(); + + virtual void onCancelKeyBind(); + virtual void onDefaultKeyBind(); + // returns true if parent failed to set key due to key being in use + virtual bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore); +}; + +class LLSetKeyBindDialog : public LLModalDialog, public LLDrawFrustum +{ +public: + LLSetKeyBindDialog(const LLSD& key); + ~LLSetKeyBindDialog(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quiting); + /*virtual*/ void draw(); + + void setParent(LLKeyBindResponderInterface* parent, U32 key_mask = DEFAULT_KEY_FILTER); + + BOOL handleKeyHere(KEY key, MASK mask); + BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); + static void onCancel(void* user_data); + static void onBlank(void* user_data); + static void onDefault(void* user_data); + static void onClickTimeout(void* user_data, MASK mask); + + class Updater; + +private: + void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore); + LLKeyBindResponderInterface* pParent; + LLCheckBoxCtrl* pCheckBox; + + U32 mKeyFilterMask; + Updater *pUpdater; +}; + + +#endif // LL_LLSETKEYBINDDIALOG_H diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3771797929..b1bdaa1c1a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -106,7 +106,6 @@ //#include "llfirstuse.h" #include "llfloaterhud.h" #include "llfloaterland.h" -#include "llfloaterpreference.h" #include "llfloatertopobjects.h" #include "llfloaterworldmap.h" #include "llgesturemgr.h" -- cgit v1.2.3