From ba2429163af92b510d26444bb33f9f9d941c6dda Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 18 Jul 2019 18:37:45 +0300 Subject: SL-11592 [Win] Ability to bind extra mouse buttons for push to talk --- indra/newview/llviewerwindow.cpp | 42 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 74770dc483..643a011ebc 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -938,6 +938,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mLeftMouseDown = down; buttonname = "Left Double Click"; break; + case LLMouseHandler::CLICK_BUTTON4: + buttonname = "Button 4"; + break; + case LLMouseHandler::CLICK_BUTTON5: + buttonname = "Button 5"; + break; } LLView::sMouseHandlerMessage.clear(); @@ -1115,7 +1121,7 @@ BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK m BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = TRUE; - LLVoiceClient::getInstance()->middleMouseState(true); + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true); handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); // Always handled as far as the OS is concerned. @@ -1267,17 +1273,47 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi return result; } - + BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - LLVoiceClient::getInstance()->middleMouseState(false); + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false); handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); // Always handled as far as the OS is concerned. return TRUE; } +BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask, S32 button, bool down) +{ + switch (button) + { + case 1: + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down); + handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down); + break; + case 2: + LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down); + handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down); + break; + default: + break; + } + + // Always handled as far as the OS is concerned. + return TRUE; +} + +BOOL LLViewerWindow::handleOtherMouseDown(LLWindow *window, LLCoordGL pos, MASK mask, S32 button) +{ + return handleOtherMouse(window, pos, mask, button, TRUE); +} + +BOOL LLViewerWindow::handleOtherMouseUp(LLWindow *window, LLCoordGL pos, MASK mask, S32 button) +{ + return handleOtherMouse(window, pos, mask, button, FALSE); +} + // WARNING: this is potentially called multiple times per frame void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask) { -- cgit v1.3 From a0bf70b41d84c50da081917f0ec842cca973f45b Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 18 Jul 2019 19:18:02 +0300 Subject: SL-11592 [Mac] Ability to bind extra mouse buttons for push to talk --- indra/llwindow/llopenglview-objc.mm | 4 +-- indra/llwindow/llwindowmacosx-objc.h | 4 +-- indra/llwindow/llwindowmacosx.cpp | 24 ++++++++++++++---- indra/llwindow/llwindowwin32.cpp | 6 +++-- indra/newview/llfloaterpreference.cpp | 47 +++++++++++++++++++---------------- indra/newview/llviewerwindow.cpp | 4 +-- 6 files changed, 54 insertions(+), 35 deletions(-) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 1990499459..decbd15efc 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -444,7 +444,7 @@ attributedStringInfo getSegments(NSAttributedString *str) NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; - callMiddleMouseDown(mMousePos, [theEvent modifierFlags]); + callOtherMouseDown(mMousePos, [theEvent modifierFlags], [theEvent buttonNumber]); } - (void) otherMouseUp:(NSEvent *)theEvent @@ -452,7 +452,7 @@ attributedStringInfo getSegments(NSAttributedString *str) NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; - callMiddleMouseUp(mMousePos, [theEvent modifierFlags]); + callOtherMouseUp(mMousePos, [theEvent modifierFlags], [theEvent buttonNumber]); } - (void) rightMouseDragged:(NSEvent *)theEvent diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 99af161102..0f77ebe7a4 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -150,8 +150,8 @@ void callWindowHide(); void callWindowUnhide(); void callWindowDidChangeScreen(); void callDeltaUpdate(float *delta, unsigned int mask); -void callMiddleMouseDown(float *pos, unsigned int mask); -void callMiddleMouseUp(float *pos, unsigned int mask); +void callOtherMouseDown(float *pos, unsigned int mask, int button); +void callOtherMouseUp(float *pos, unsigned int mask, int button); void callFocus(); void callFocusLost(); void callModifier(unsigned int mask); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 3554f90be8..6749b3be3b 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -417,7 +417,7 @@ void callDeltaUpdate(float *delta, MASK mask) gWindowImplementation->updateMouseDeltas(delta); } -void callMiddleMouseDown(float *pos, MASK mask) +void callOtherMouseDown(float *pos, MASK mask, int button) { LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); @@ -426,10 +426,17 @@ void callMiddleMouseDown(float *pos, MASK mask) gWindowImplementation->getMouseDeltas(deltas); outCoords.mX += deltas[0]; outCoords.mY += deltas[1]; - gWindowImplementation->getCallbacks()->handleMiddleMouseDown(gWindowImplementation, outCoords, mask); + if (button == 3) + { + gWindowImplementation->getCallbacks()->handleMiddleMouseDown(gWindowImplementation, outCoords, mask); + } + else + { + gWindowImplementation->getCallbacks()->handleOtherMouseDown(gWindowImplementation, outCoords, mask, button); + } } -void callMiddleMouseUp(float *pos, MASK mask) +void callOtherMouseUp(float *pos, MASK mask, int button) { LLCoordGL outCoords; outCoords.mX = ll_round(pos[0]); @@ -437,8 +444,15 @@ void callMiddleMouseUp(float *pos, MASK mask) float deltas[2]; gWindowImplementation->getMouseDeltas(deltas); outCoords.mX += deltas[0]; - outCoords.mY += deltas[1]; - gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask); + outCoords.mY += deltas[1]; + if (button == 3) + { + gWindowImplementation->getCallbacks()->handleMiddleMouseUp(gWindowImplementation, outCoords, mask); + } + else + { + gWindowImplementation->getCallbacks()->handleOtherMouseUp(gWindowImplementation, outCoords, mask, button); + } } void callModifier(MASK mask) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 25286ee61c..5fe907d240 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2567,7 +2567,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button)) + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + if (window_imp->mCallbacks->handleOtherMouseDown(window_imp, gl_coord, mask, button + 3)) { return 0; } @@ -2597,7 +2598,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ MASK mask = gKeyboard->currentMask(TRUE); // generate move event to update mouse coordinates window_imp->mCallbacks->handleMouseMove(window_imp, gl_coord, mask); - if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button)) + // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 + if (window_imp->mCallbacks->handleOtherMouseUp(window_imp, gl_coord, mask, button + 3)) { return 0; } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5f74aaa5dd..27a597a631 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -217,7 +217,9 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask) BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) { BOOL result = FALSE; - if (down && clicktype >= 3 && mask == 0) + if (down + && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5) + && mask == 0) { mParent->setMouse(clicktype); result = TRUE; @@ -1716,29 +1718,30 @@ void LLFloaterPreference::setKey(KEY key) void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click) { - if (click >= LLMouseHandler::CLICK_MIDDLE) + std::string bt_name; + std::string ctrl_value; + switch (click) + { + case LLMouseHandler::CLICK_MIDDLE: + bt_name = "middle_mouse"; + ctrl_value = MIDDLE_MOUSE_CV; + break; + case LLMouseHandler::CLICK_BUTTON4: + bt_name = "button4_mouse"; + ctrl_value = MOUSE_BUTTON_4_CV; + break; + case LLMouseHandler::CLICK_BUTTON5: + bt_name = "button5_mouse"; + ctrl_value = MOUSE_BUTTON_5_CV; + break; + default: + break; + } + + if (!ctrl_value.empty()) { - std::string bt_name; - std::string ctrl_value; - switch (click) - { - case LLMouseHandler::CLICK_MIDDLE: - bt_name = "middle_mouse"; - ctrl_value = MIDDLE_MOUSE_CV; - break; - case LLMouseHandler::CLICK_BUTTON4: - bt_name = "button4_mouse"; - ctrl_value = MOUSE_BUTTON_4_CV; - break; - case LLMouseHandler::CLICK_BUTTON5: - bt_name = "button5_mouse"; - ctrl_value = MOUSE_BUTTON_5_CV; - break; - default: - break; - } - // We are using text names for readability LLUICtrl* p2t_line_editor = getChild("modifier_combo"); + // We are using text control names for readability and compatibility with voice p2t_line_editor->setControlValue(ctrl_value); LLPanel* advanced_preferences = dynamic_cast(p2t_line_editor->getParent()); if (advanced_preferences) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 643a011ebc..9afe85a6f5 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1288,11 +1288,11 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask { switch (button) { - case 1: + case 4: LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down); handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down); break; - case 2: + case 5: LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down); handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down); break; -- cgit v1.3 From b1b102cf662b9deb00c6231ca335fcf46b86034c Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 26 Jul 2019 21:10:01 +0300 Subject: SL-8380 Ability to disable 2D UI tooltips --- indra/llui/llview.cpp | 14 ++++++++++---- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llviewerwindow.cpp | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 89ad8138d8..0e81277185 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -875,10 +875,16 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask) F32 timeout = LLToolTipMgr::instance().toolTipVisible() ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" ) : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" ); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(tooltip) - .sticky_rect(calcScreenRect()) - .delay_time(timeout)); + + // Even if we don't show tooltips, consume the event, nothing below should show tooltip + bool allow_ui_tooltips = LLUI::sSettingGroups["config"]->getBOOL( "BasicUITooltips" ); + if (allow_ui_tooltips) + { + LLToolTipMgr::instance().show(LLToolTip::Params() + .message(tooltip) + .sticky_rect(calcScreenRect()) + .delay_time(timeout)); + } handled = TRUE; } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 472a76a7e2..b4919c6e48 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11219,6 +11219,17 @@ Value 1 + BasicUITooltips + + Comment + Show tooltips for various 2D UI elements like buttons or checkboxes, won't supress tooltips like drag'n'drop, inworld, links or media + Persist + 1 + Type + Boolean + Value + 1 + ShowHoverTips Comment diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 9afe85a6f5..7f3e1faa33 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3367,7 +3367,8 @@ void LLViewerWindow::updateUI() LLRect screen_sticky_rect = mRootView->getLocalRect(); S32 local_x, local_y; - if (gSavedSettings.getBOOL("DebugShowXUINames")) + static LLCachedControl debug_show_xui_names(gSavedSettings, "DebugShowXUINames", 0); + if (debug_show_xui_names) { LLToolTip::Params params; -- cgit v1.3 From 98b28e58813035df597d01e18657b73a94635ecd Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 10 Sep 2019 19:49:15 +0300 Subject: SL-11910 [Win] Horizontal scroll --- indra/llui/llscrollbar.cpp | 10 ++++++++ indra/llui/llscrollbar.h | 1 + indra/llui/llscrollcontainer.cpp | 19 ++++++++++++++ indra/llui/llscrollcontainer.h | 1 + indra/llui/llscrolllistctrl.cpp | 14 +++++++++++ indra/llui/llscrolllistctrl.h | 1 + indra/llui/lltextbase.cpp | 1 + indra/llui/lltextbase.h | 1 + indra/llui/llview.cpp | 10 ++++++++ indra/llui/llview.h | 2 ++ indra/llwindow/llmousehandler.h | 1 + indra/llwindow/llwindowcallbacks.cpp | 4 +++ indra/llwindow/llwindowcallbacks.h | 1 + indra/llwindow/llwindowwin32.cpp | 36 +++++++++++++++++++++++++++ indra/newview/llmediactrl.cpp | 14 +++++++++++ indra/newview/llmediactrl.h | 1 + indra/newview/lltool.cpp | 6 +++++ indra/newview/lltool.h | 1 + indra/newview/lltoolpie.cpp | 5 ++++ indra/newview/lltoolpie.h | 1 + indra/newview/llviewermedia.h | 1 + indra/newview/llviewerwindow.cpp | 48 ++++++++++++++++++++++++++++++++++++ indra/newview/llviewerwindow.h | 2 ++ 23 files changed, 181 insertions(+) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 76134144a0..25daf9db8b 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -408,6 +408,16 @@ BOOL LLScrollbar::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +BOOL LLScrollbar::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + BOOL handled = FALSE; + if (LLScrollbar::HORIZONTAL == mOrientation) + { + handled = changeLine(clicks * mStepSize, TRUE); + } + return handled; +} + BOOL LLScrollbar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg) { diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index e2bf52c14b..5f2f490d81 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -88,6 +88,7 @@ public: virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string &tooltip_msg); diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 6135cc56ad..3db38bbfac 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -272,6 +272,25 @@ BOOL LLScrollContainer::handleScrollWheel( S32 x, S32 y, S32 clicks ) return FALSE; } +BOOL LLScrollContainer::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + if (LLUICtrl::handleScrollHWheel(x,y,clicks)) + { + return TRUE; + } + + LLScrollbar* horizontal = mScrollbar[HORIZONTAL]; + if (horizontal->getVisible() + && horizontal->getEnabled() + && horizontal->handleScrollHWheel( 0, 0, clicks ) ) + { + updateScroll(); + return TRUE; + } + + return FALSE; +} + BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index e6c7891397..c14099dbd5 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -107,6 +107,7 @@ public: virtual BOOL handleKeyHere(KEY key, MASK mask); virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); + virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks ); virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void* cargo_data, diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f4028057e8..6c8fde580f 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1601,6 +1601,20 @@ BOOL LLScrollListCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks) return handled; } +BOOL LLScrollListCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + BOOL handled = FALSE; + // Pretend the mouse is over the scrollbar + handled = mScrollbar->handleScrollHWheel( 0, 0, clicks ); + + if (mMouseWheelOpaque) + { + return TRUE; + } + + return handled; +} + // *NOTE: Requires a valid row_index and column_index LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index) { diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index b35a8608e7..d7572d9fcf 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -317,6 +317,7 @@ public: /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); /*virtual*/ BOOL handleUnicodeCharHere(llwchar uni_char); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ void setEnabled(BOOL enabled); /*virtual*/ void setFocus( BOOL b ); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index a23741b6dd..00443a16b2 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -3113,6 +3113,7 @@ BOOL LLTextSegment::handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; BOOL LLTextSegment::handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; } BOOL LLTextSegment::handleHover(S32 x, S32 y, MASK mask) { return FALSE; } BOOL LLTextSegment::handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; } +BOOL LLTextSegment::handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; } BOOL LLTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { return FALSE; } const std::string& LLTextSegment::getName() const { diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 9831c35858..4239cdf43c 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -103,6 +103,7 @@ public: /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ const std::string& getName() const; /*virtual*/ void onMouseCaptureLost(); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 0e81277185..b0e346f513 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1060,6 +1060,11 @@ BOOL LLView::handleScrollWheel(S32 x, S32 y, S32 clicks) return childrenHandleScrollWheel( x, y, clicks ) != NULL; } +BOOL LLView::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return childrenHandleScrollHWheel( x, y, clicks ) != NULL; +} + BOOL LLView::handleRightMouseDown(S32 x, S32 y, MASK mask) { return childrenHandleRightMouseDown( x, y, mask ) != NULL; @@ -1085,6 +1090,11 @@ LLView* LLView::childrenHandleScrollWheel(S32 x, S32 y, S32 clicks) return childrenHandleMouseEvent(&LLView::handleScrollWheel, x, y, clicks, false); } +LLView* LLView::childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return childrenHandleMouseEvent(&LLView::handleScrollHWheel, x, y, clicks, false); +} + // Called during downward traversal LLView* LLView::childrenHandleKey(KEY key, MASK mask) { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 8494bb338a..b448cc8397 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -426,6 +426,7 @@ public: /*virtual*/ BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); @@ -556,6 +557,7 @@ protected: LLView* childrenHandleMiddleMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleDoubleClick(S32 x, S32 y, MASK mask); LLView* childrenHandleScrollWheel(S32 x, S32 y, S32 clicks); + LLView* childrenHandleScrollHWheel(S32 x, S32 y, S32 clicks); LLView* childrenHandleRightMouseDown(S32 x, S32 y, MASK mask); LLView* childrenHandleRightMouseUp(S32 x, S32 y, MASK mask); LLView* childrenHandleToolTip(S32 x, S32 y, MASK mask); diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h index 8e6fbdb4e3..1dcd0348d8 100644 --- a/indra/llwindow/llmousehandler.h +++ b/indra/llwindow/llmousehandler.h @@ -66,6 +66,7 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0; virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0; + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) = 0; virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0; virtual const std::string& getName() const = 0; diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index c01f574375..be61e1e16c 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -130,6 +130,10 @@ void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks) { } +void LLWindowCallbacks::handleScrollHWheel(LLWindow *window, S32 clicks) +{ +} + void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height) { } diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index 9304446f8f..3b18648138 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -56,6 +56,7 @@ public: virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask); virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask); virtual void handleScrollWheel(LLWindow *window, S32 clicks); + virtual void handleScrollHWheel(LLWindow *window, S32 clicks); virtual void handleResize(LLWindow *window, S32 width, S32 height); virtual void handleFocus(LLWindow *window); virtual void handleFocusLost(LLWindow *window); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 8fefb119bc..3c69aa98c4 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2662,6 +2662,42 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ return 0; } */ + case WM_MOUSEHWHEEL: + { + window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL"); + static short h_delta = 0; + + RECT client_rect; + + // eat scroll events that occur outside our window, since we use mouse position to direct scroll + // instead of keyboard focus + // NOTE: mouse_coord is in *window* coordinates for scroll events + POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)}; + + if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord) + && GetClientRect(window_imp->mWindowHandle, &client_rect)) + { + // we have a valid mouse point and client rect + if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x + || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y) + { + // mouse is outside of client rect, so don't do anything + return 0; + } + } + + S16 incoming_h_delta = HIWORD(w_param); + h_delta += incoming_h_delta; + + // If the user rapidly spins the wheel, we can get messages with + // large deltas, like 480 or so. Thus we need to scroll more quickly. + if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta) + { + window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA); + h_delta = 0; + } + return 0; + } // Handle mouse movement within the window case WM_MOUSEMOVE: { diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 1d3a026049..6cab9b9e99 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -210,6 +210,20 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) return TRUE; } +//////////////////////////////////////////////////////////////////////////////// +// +BOOL LLMediaCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + if (LLPanel::handleScrollHWheel(x, y, clicks)) return TRUE; + if (mMediaSource && mMediaSource->hasMedia()) + { + convertInputCoords(x, y); + mMediaSource->scrollWheel(x, y, clicks, 0, gKeyboard->currentMask(TRUE)); + } + + return TRUE; +} + //////////////////////////////////////////////////////////////////////////////// // virtual BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask) diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 11400c8274..958c76f261 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -92,6 +92,7 @@ public: virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); + virtual BOOL handleScrollHWheel( S32 x, S32 y, S32 clicks ); virtual BOOL handleToolTip(S32 x, S32 y, MASK mask); // navigation diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index b5d78f3654..c5e31ff8e6 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -115,6 +115,12 @@ BOOL LLTool::handleScrollWheel(S32 x, S32 y, S32 clicks) return FALSE; } +BOOL LLTool::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + // by default, didn't handle it + return FALSE; +} + BOOL LLTool::handleDoubleClick(S32 x,S32 y,MASK mask) { // LL_INFOS() << "LLTool::handleDoubleClick" << LL_ENDL; diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h index c5bad9d532..308983afda 100644 --- a/indra/newview/lltool.h +++ b/indra/newview/lltool.h @@ -57,6 +57,7 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 47227f987d..6c1ae7159b 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -208,6 +208,11 @@ BOOL LLToolPie::handleScrollWheel(S32 x, S32 y, S32 clicks) return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); } +BOOL LLToolPie::handleScrollHWheel(S32 x, S32 y, S32 clicks) +{ + return LLViewerMediaFocus::getInstance()->handleScrollWheel(x, y, clicks); +} + // True if you selected an object. BOOL LLToolPie::handleLeftClickPick() { diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 95d155a474..fe0acfe473 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -50,6 +50,7 @@ public: virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks); virtual BOOL handleToolTip(S32 x, S32 y, MASK mask); virtual void render(); diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 03d97a3a72..9896399774 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -314,6 +314,7 @@ public: /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) { return FALSE; }; /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) { return FALSE; }; + /*virtual*/ BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) { return FALSE; }; /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) { return FALSE; }; /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }; /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) { return FALSE; }; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ea846805c2..72df31cb5f 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1587,6 +1587,11 @@ void LLViewerWindow::handleScrollWheel(LLWindow *window, S32 clicks) handleScrollWheel( clicks ); } +void LLViewerWindow::handleScrollHWheel(LLWindow *window, S32 clicks) +{ + handleScrollHWheel(clicks); +} + void LLViewerWindow::handleWindowBlock(LLWindow *window) { send_agent_pause(); @@ -3004,6 +3009,49 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) return; } +void LLViewerWindow::handleScrollHWheel(S32 clicks) +{ + LLUI::resetMouseIdleTimer(); + + LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture(); + if (mouse_captor) + { + S32 local_x; + S32 local_y; + mouse_captor->screenPointToLocal(mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y); + mouse_captor->handleScrollHWheel(local_x, local_y, clicks); + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Scroll Horizontal Wheel handled by captor " << mouse_captor->getName() << LL_ENDL; + } + return; + } + + LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl(); + if (top_ctrl) + { + S32 local_x; + S32 local_y; + top_ctrl->screenPointToLocal(mCurrentMousePoint.mX, mCurrentMousePoint.mY, &local_x, &local_y); + if (top_ctrl->handleScrollHWheel(local_x, local_y, clicks)) return; + } + + if (mRootView->handleScrollHWheel(mCurrentMousePoint.mX, mCurrentMousePoint.mY, clicks)) + { + if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Scroll Horizontal Wheel" << LLView::sMouseHandlerMessage << LL_ENDL; + } + return; + } + else if (LLView::sDebugMouseHandling) + { + LL_INFOS() << "Scroll Horizontal Wheel not handled by view" << LL_ENDL; + } + + return; +} + void LLViewerWindow::addPopup(LLView* popup) { if (mPopupView) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index d084642fdc..385bbd57e5 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -208,6 +208,7 @@ public: /*virtual*/ void handleMenuSelect(LLWindow *window, S32 menu_item); /*virtual*/ BOOL handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S32 height); /*virtual*/ void handleScrollWheel(LLWindow *window, S32 clicks); + /*virtual*/ void handleScrollHWheel(LLWindow *window, S32 clicks); /*virtual*/ BOOL handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ void handleWindowBlock(LLWindow *window); /*virtual*/ void handleWindowUnblock(LLWindow *window); @@ -326,6 +327,7 @@ public: BOOL handleKey(KEY key, MASK mask); BOOL handleKeyUp(KEY key, MASK mask); void handleScrollWheel (S32 clicks); + void handleScrollHWheel (S32 clicks); // add and remove views from "popup" layer void addPopup(LLView* popup); -- cgit v1.3 From 63a3d9b4d99d244481dbd33c184d3ff8039ca7ad Mon Sep 17 00:00:00 2001 From: NiranV Date: Wed, 4 Sep 2019 04:23:42 +0200 Subject: SL-12104 Fixed: Oversized snapshots being broken. --- indra/newview/llviewerwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 72df31cb5f..a7601fc30c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4719,7 +4719,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) && (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) { - if (scratch_space.allocate(image_width, image_height, GL_DEPTH_COMPONENT, true, true)) + U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA; + if (scratch_space.allocate(image_width, image_height, color_fmt, true, true)) { original_width = gPipeline.mDeferredScreen.getWidth(); original_height = gPipeline.mDeferredScreen.getHeight(); -- cgit v1.3 From 07635d22f567cd0aeb9addf5ac22b02fa1da0e6c Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 22 Oct 2019 17:17:12 +0300 Subject: SL-12173 Crash on setShape --- indra/newview/llviewerwindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a7601fc30c..f3de5f03cd 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1994,6 +1994,11 @@ void LLViewerWindow::initBase() LLPanel* panel_holder = main_view->getChild("toolbar_view_holder"); // Load the toolbar view from file gToolBarView = LLUICtrlFactory::getInstance()->createFromFile("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance()); + if (!gToolBarView) + { + LL_ERRS() << "Failed to initialize viewer: Viewer couldn't process file panel_toolbar_view.xml, " + << "if this problem happens again, please validate your installation." << LL_ENDL; + } gToolBarView->setShape(panel_holder->getLocalRect()); // Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI()) gToolBarView->setVisible(FALSE); -- cgit v1.3 From 39dc22d1adddb85a8b5edd5a30ad7750e9f19142 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 24 Oct 2019 18:47:47 +0300 Subject: SL-12185 [mac] crash when typing letters while viewer is loading --- indra/newview/llviewerwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f3de5f03cd..1e2b2c37d0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2884,7 +2884,8 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // If "Pressing letter keys starts local chat" option is selected, we are not in mouselook, // no view has keyboard focus, this is a printable character key (and no modifier key is // pressed except shift), then give focus to nearby chat (STORM-560) - if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && + if ( LLStartUp::getStartupState() >= STATE_STARTED && + gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && !keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) ) { // Initialize nearby chat if it's missing -- cgit v1.3 From dcb1bea0f6086d963fba8b374d0294223bf66a11 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 19 Sep 2019 16:55:28 +0300 Subject: SL-6109 Implement keybindings --- indra/llcommon/CMakeLists.txt | 2 + indra/llcommon/indra_constants.h | 10 +++ indra/llcommon/llkeybind.cpp | 147 ++++++++++++++++++++++++++++++++++ indra/llcommon/llkeybind.h | 70 ++++++++++++++++ indra/llwindow/llmousehandler.cpp | 2 +- indra/llwindow/llmousehandler.h | 12 +-- indra/llxml/CMakeLists.txt | 1 - indra/llxml/llcontrol.h | 2 - indra/llxml/llcontrolgroupreader.h | 80 ------------------ indra/newview/llfloaterpreference.cpp | 14 ++-- indra/newview/llfloaterpreference.h | 2 +- indra/newview/lltool.cpp | 2 +- indra/newview/lltool.h | 2 +- indra/newview/lltoolpie.cpp | 2 +- indra/newview/lltoolpie.h | 2 +- indra/newview/llviewerwindow.cpp | 39 +++++---- indra/newview/llviewerwindow.h | 2 +- indra/newview/llvoiceclient.cpp | 8 +- indra/newview/llvoiceclient.h | 2 +- 19 files changed, 268 insertions(+), 133 deletions(-) create mode 100644 indra/llcommon/llkeybind.cpp create mode 100644 indra/llcommon/llkeybind.h delete mode 100644 indra/llxml/llcontrolgroupreader.h (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index af41b9e460..7e52a620db 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -73,6 +73,7 @@ set(llcommon_SOURCE_FILES llinitparam.cpp llinitdestroyclass.cpp llinstancetracker.cpp + llkeybind.cpp llleap.cpp llleaplistener.cpp llliveappconfig.cpp @@ -183,6 +184,7 @@ set(llcommon_HEADER_FILES llinitdestroyclass.h llinitparam.h llinstancetracker.h + llkeybind.h llkeythrottle.h llleap.h llleaplistener.h diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 0fbf4b966b..e763d413e5 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -54,6 +54,16 @@ enum ETerrainBrushType E_LANDBRUSH_INVALID = 6 }; +enum EMouseClickType{ + CLICK_NONE = -1, + CLICK_LEFT = 0, + CLICK_MIDDLE, + CLICK_RIGHT, + CLICK_BUTTON4, + CLICK_BUTTON5, + CLICK_DOUBLELEFT +}; + // keys // Bit masks for various keyboard modifier keys. const MASK MASK_NONE = 0x0000; diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp new file mode 100644 index 0000000000..f227c0a1a5 --- /dev/null +++ b/indra/llcommon/llkeybind.cpp @@ -0,0 +1,147 @@ +/** + * @file llkeybind.cpp + * @brief Information about key combinations. + * + * $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 "linden_common.h" + +#include "llkeybind.h" + +#include "llsd.h" +#include "llsdutil.h" + +LLKeyData::LLKeyData() + : mMouse(CLICK_NONE), mKey(KEY_NONE), mMask(MASK_NONE) +{ +} + +LLKeyData::LLKeyData(const LLSD &key_data) +{ + mMouse = (EMouseClickType)key_data["mouse"].asInteger(); + mKey = key_data["key"].asInteger(); + mMask = key_data["mask"].asInteger(); +} + +LLSD LLKeyData::asLLSD() const +{ + LLSD data; + data["mouse"] = (LLSD::Integer)mMouse; + data["key"] = (LLSD::Integer)mKey; + data["mask"] = (LLSD::Integer)mMask; + return data; +} + +bool LLKeyData::isEmpty() const +{ + return mMouse == CLICK_NONE && mKey == KEY_NONE && mMask == MASK_NONE; +} + +void LLKeyData::reset() +{ + mMouse = CLICK_NONE; + mKey = KEY_NONE; + mMask = MASK_NONE; +} + +LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) +{ + mMouse = rhs.mMouse; + mKey = rhs.mKey; + mMask = rhs.mMask; + return *this; +} + +// LLKeyBind + +LLKeyBind::LLKeyBind(const LLSD &key_bind) +{ + if (key_bind.has("DataPrimary")) + { + mDataPrimary = LLKeyData(key_bind["DataPrimary"]); + } + if (key_bind.has("DataSecondary")) + { + mDataSecondary = LLKeyData(key_bind["DataSecondary"]); + } +} + +bool LLKeyBind::operator==(const LLKeyBind& rhs) +{ + if (mDataPrimary.mMouse != rhs.mDataPrimary.mMouse) return false; + if (mDataPrimary.mKey != rhs.mDataPrimary.mKey) return false; + if (mDataPrimary.mMask != rhs.mDataPrimary.mMask) return false; + if (mDataSecondary.mMouse != rhs.mDataSecondary.mMouse) return false; + if (mDataSecondary.mKey != rhs.mDataSecondary.mKey) return false; + if (mDataSecondary.mMask != rhs.mDataSecondary.mMask) return false; + return true; +} + +bool LLKeyBind::empty() +{ + if (mDataPrimary.mMouse != CLICK_NONE) return false; + if (mDataPrimary.mKey != KEY_NONE) return false; + if (mDataPrimary.mMask != MASK_NONE) return false; + if (mDataSecondary.mMouse != CLICK_NONE) return false; + if (mDataSecondary.mKey != KEY_NONE) return false; + if (mDataSecondary.mMask != MASK_NONE) return false; + return false; +} + +LLSD LLKeyBind::asLLSD() const +{ + LLSD data; + if (!mDataPrimary.isEmpty()) + { + data["DataPrimary"] = mDataPrimary.asLLSD(); + } + if (!mDataSecondary.isEmpty()) + { + data["DataSecondary"] = mDataSecondary.asLLSD(); + } + return data; +} + +bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const +{ + if (mDataPrimary.mKey == key && mDataPrimary.mMask == mask && mDataPrimary.mMouse == mouse) + { + return true; + } + if (mDataSecondary.mKey == key && mDataSecondary.mMask == mask && mDataSecondary.mMouse == mouse) + { + return true; + } + return false; +} + +bool LLKeyBind::canHandleKey(KEY key, MASK mask) const +{ + return canHandle(CLICK_NONE, key, mask); +} + +bool LLKeyBind::canHandleMouse(EMouseClickType mouse, MASK mask) const +{ + return canHandle(mouse, KEY_NONE, mask); +} + diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h new file mode 100644 index 0000000000..4fe622fb79 --- /dev/null +++ b/indra/llcommon/llkeybind.h @@ -0,0 +1,70 @@ +/** + * @file llkeybind.h + * @brief Information about key combinations. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_KEYBIND_H +#define LL_KEYBIND_H + +#include "indra_constants.h" + +// KeyData - single key combination (mouse/mask/keyboard) +class LL_COMMON_API LLKeyData +{ +public: + LLKeyData(); + LLKeyData(const LLSD &key_data); + + LLSD asLLSD() const; + bool isEmpty() const; + void reset(); + LLKeyData& operator=(const LLKeyData& rhs); + + EMouseClickType mMouse; + KEY mKey; + MASK mMask; +}; + +// One function can bind to multiple Key options +class LLKeyBind +{ +public: + LLKeyBind() {} + LLKeyBind(const LLSD &key_bind); + + bool operator==(const LLKeyBind& rhs); + bool empty(); + + LLSD asLLSD() const; + + bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const; + bool canHandleKey(KEY key, MASK mask) const; + bool canHandleMouse(EMouseClickType mouse, MASK mask) const; + + LLKeyData mDataPrimary; + LLKeyData mDataSecondary; +}; + + +#endif // LL_KEYBIND_H diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp index d5fa65fe4b..e41ebd42f3 100644 --- a/indra/llwindow/llmousehandler.cpp +++ b/indra/llwindow/llmousehandler.cpp @@ -27,7 +27,7 @@ #include "llmousehandler.h" //virtual -BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down) +BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) { BOOL handled = FALSE; if (down) diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h index 1dcd0348d8..d221dd117c 100644 --- a/indra/llwindow/llmousehandler.h +++ b/indra/llwindow/llmousehandler.h @@ -29,6 +29,7 @@ #include "linden_common.h" #include "llrect.h" +#include "indra_constants.h" // Mostly-abstract interface. // Intended for use via multiple inheritance. @@ -46,16 +47,7 @@ public: SHOW_ALWAYS, } EShowToolTip; - typedef enum { - CLICK_LEFT, - CLICK_MIDDLE, - CLICK_RIGHT, - CLICK_BUTTON4, - CLICK_BUTTON5, - CLICK_DOUBLELEFT - } EClickType; - - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0; virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0; virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0; diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index 17400a203e..013a422d35 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -28,7 +28,6 @@ set(llxml_HEADER_FILES CMakeLists.txt llcontrol.h - llcontrolgroupreader.h llxmlnode.h llxmlparser.h llxmltree.h diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index de0d366492..9312bbc91a 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -34,8 +34,6 @@ #include "llrefcount.h" #include "llinstancetracker.h" -#include "llcontrolgroupreader.h" - #include // *NOTE: boost::visit_each<> generates warning 4675 on .net 2003 diff --git a/indra/llxml/llcontrolgroupreader.h b/indra/llxml/llcontrolgroupreader.h deleted file mode 100644 index 6a27a65499..0000000000 --- a/indra/llxml/llcontrolgroupreader.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file llcontrolgroupreader.h - * @brief Interface providing readonly access to LLControlGroup (intended for unit testing) - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLCONTROLGROUPREADER_H -#define LL_LLCONTROLGROUPREADER_H - -#include "stdtypes.h" -#include - -#include "v3math.h" -#include "v3dmath.h" -#include "v3color.h" -#include "v4color.h" -#include "llrect.h" - -class LLControlGroupReader -{ -public: - LLControlGroupReader() {} - virtual ~LLControlGroupReader() {} - - virtual std::string getString(const std::string& name) { return ""; } - virtual LLWString getWString(const std::string& name) { return LLWString(); } - virtual std::string getText(const std::string& name) { return ""; } - virtual LLVector3 getVector3(const std::string& name) { return LLVector3(); } - virtual LLVector3d getVector3d(const std::string& name) { return LLVector3d(); } - virtual LLRect getRect(const std::string& name) { return LLRect(); } - virtual BOOL getBOOL(const std::string& name) { return FALSE; } - virtual S32 getS32(const std::string& name) { return 0; } - virtual F32 getF32(const std::string& name) {return 0.0f; } - virtual U32 getU32(const std::string& name) {return 0; } - virtual LLSD getLLSD(const std::string& name) { return LLSD(); } - - virtual LLColor4 getColor(const std::string& name) { return LLColor4(); } - virtual LLColor4 getColor4(const std::string& name) { return LLColor4(); } - virtual LLColor3 getColor3(const std::string& name) { return LLColor3(); } - - virtual void setBOOL(const std::string& name, BOOL val) {} - virtual void setS32(const std::string& name, S32 val) {} - virtual void setF32(const std::string& name, F32 val) {} - virtual void setU32(const std::string& name, U32 val) {} - virtual void setString(const std::string& name, const std::string& val) {} - virtual void setVector3(const std::string& name, const LLVector3 &val) {} - virtual void setVector3d(const std::string& name, const LLVector3d &val) {} - virtual void setRect(const std::string& name, const LLRect &val) {} - virtual void setColor4(const std::string& name, const LLColor4 &val) {} - virtual void setLLSD(const std::string& name, const LLSD& val) {} -}; - -#endif /* LL_LLCONTROLGROUPREADER_H */ - - - - - - - diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index b48495b5b2..9282196b86 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -170,7 +170,7 @@ public: void setParent(LLFloaterPreference* parent) { mParent = parent; } BOOL handleKeyHere(KEY key, MASK mask); - BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); + BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); static void onCancel(void* user_data); private: @@ -214,11 +214,11 @@ BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask) return result; } -BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) +BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) { BOOL result = FALSE; if (down - && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5) + && (clicktype == CLICK_MIDDLE || clicktype == CLICK_BUTTON4 || clicktype == CLICK_BUTTON5) && mask == 0) { mParent->setMouse(clicktype); @@ -1717,21 +1717,21 @@ void LLFloaterPreference::setKey(KEY key) getChild("modifier_combo")->onCommit(); } -void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click) +void LLFloaterPreference::setMouse(EMouseClickType click) { std::string bt_name; std::string ctrl_value; switch (click) { - case LLMouseHandler::CLICK_MIDDLE: + case CLICK_MIDDLE: bt_name = "middle_mouse"; ctrl_value = MIDDLE_MOUSE_CV; break; - case LLMouseHandler::CLICK_BUTTON4: + case CLICK_BUTTON4: bt_name = "button4_mouse"; ctrl_value = MOUSE_BUTTON_4_CV; break; - case LLMouseHandler::CLICK_BUTTON5: + case CLICK_BUTTON5: bt_name = "button5_mouse"; ctrl_value = MOUSE_BUTTON_5_CV; break; diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 4412c95473..9190ef8ebd 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -148,7 +148,7 @@ public: void onSelectSkin(); void onClickSetKey(); void setKey(KEY key); - void setMouse(LLMouseHandler::EClickType click); + void setMouse(EMouseClickType click); void onClickSetMiddleMouse(); void onClickSetSounds(); void onClickEnablePopup(); diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index c5e31ff8e6..0038138078 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -60,7 +60,7 @@ LLTool::~LLTool() } } -BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) +BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) { BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down); diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h index 308983afda..41a38804ce 100644 --- a/indra/newview/lltool.h +++ b/indra/newview/lltool.h @@ -49,7 +49,7 @@ public: virtual BOOL isView() const { return FALSE; } // Virtual functions inherited from LLMouseHandler - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 6c1ae7159b..0b569b4fe8 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -91,7 +91,7 @@ LLToolPie::LLToolPie() { } -BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down) +BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down) { BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down); diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index fe0acfe473..6d0e25eaeb 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -42,7 +42,7 @@ class LLToolPie : public LLTool, public LLSingleton public: // Virtual functions inherited from LLMouseHandler - virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down); + virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down); virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1e2b2c37d0..2c58295814 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -898,7 +898,7 @@ LLViewerWindow::Params::Params() {} -BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down) +BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) { const char* buttonname = ""; const char* buttonstatestr = ""; @@ -907,6 +907,8 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK 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)) { @@ -922,26 +924,26 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK switch (clicktype) { - case LLMouseHandler::CLICK_LEFT: + case CLICK_LEFT: mLeftMouseDown = down; buttonname = "Left"; break; - case LLMouseHandler::CLICK_RIGHT: + case CLICK_RIGHT: mRightMouseDown = down; buttonname = "Right"; break; - case LLMouseHandler::CLICK_MIDDLE: + case CLICK_MIDDLE: mMiddleMouseDown = down; buttonname = "Middle"; break; - case LLMouseHandler::CLICK_DOUBLELEFT: + case CLICK_DOUBLELEFT: mLeftMouseDown = down; buttonname = "Left Double Click"; break; - case LLMouseHandler::CLICK_BUTTON4: + case CLICK_BUTTON4: buttonname = "Button 4"; break; - case LLMouseHandler::CLICK_BUTTON5: + case CLICK_BUTTON5: buttonname = "Button 5"; break; } @@ -1059,7 +1061,7 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask mMouseDownTimer.reset(); } BOOL down = TRUE; - return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); + return handleAnyMouseClick(window, pos, mask, CLICK_LEFT, down); } BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1067,8 +1069,7 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma // try handling as a double-click first, then a single-click if that // wasn't handled. BOOL down = TRUE; - if (handleAnyMouseClick(window, pos, mask, - LLMouseHandler::CLICK_DOUBLELEFT, down)) + if (handleAnyMouseClick(window, pos, mask, CLICK_DOUBLELEFT, down)) { return TRUE; } @@ -1082,7 +1083,7 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) mMouseDownTimer.stop(); } BOOL down = FALSE; - return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down); + return handleAnyMouseClick(window, pos, mask, CLICK_LEFT, down); } @@ -1094,7 +1095,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK y = ll_round((F32)y / mDisplayScale.mV[VY]); BOOL down = TRUE; - BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); + BOOL handle = handleAnyMouseClick(window, pos, mask, CLICK_RIGHT, down); if (handle) return handle; @@ -1115,14 +1116,13 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down); + return handleAnyMouseClick(window, pos, mask, CLICK_RIGHT, down); } BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = TRUE; - LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true); - handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); + handleAnyMouseClick(window, pos, mask, CLICK_MIDDLE, down); // Always handled as far as the OS is concerned. return TRUE; @@ -1277,8 +1277,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false); - handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down); + handleAnyMouseClick(window, pos, mask, CLICK_MIDDLE, down); // Always handled as far as the OS is concerned. return TRUE; @@ -1289,12 +1288,10 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask switch (button) { case 4: - LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down); - handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down); + handleAnyMouseClick(window, pos, mask, CLICK_BUTTON4, down); break; case 5: - LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down); - handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down); + handleAnyMouseClick(window, pos, mask, CLICK_BUTTON5, down); break; default: break; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 385bbd57e5..5f03685cee 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -176,7 +176,7 @@ public: void setUIVisibility(bool); bool getUIVisibility(); - BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); // // LLWindowCallback interface implementation diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index bce399a940..e7a8a78c14 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -641,15 +641,15 @@ void LLVoiceClient::setPTTKey(std::string &key) // Value is stored as text for readability if(key == "MiddleMouse") { - mPTTMouseButton = LLMouseHandler::CLICK_MIDDLE; + mPTTMouseButton = CLICK_MIDDLE; } else if(key == "MouseButton4") { - mPTTMouseButton = LLMouseHandler::CLICK_BUTTON4; + mPTTMouseButton = CLICK_BUTTON4; } else if (key == "MouseButton5") { - mPTTMouseButton = LLMouseHandler::CLICK_BUTTON5; + mPTTMouseButton = CLICK_BUTTON5; } else { @@ -711,7 +711,7 @@ void LLVoiceClient::keyUp(KEY key, MASK mask) } } } -void LLVoiceClient::updateMouseState(S32 click, bool down) +void LLVoiceClient::updateMouseState(S32 click, MASK mask, bool down) { if(mPTTMouseButton == click && LLAgent::isActionAllowed("speak")) { diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index fbc85fd977..e3285b0c9b 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -418,7 +418,7 @@ public: // PTT key triggering void keyDown(KEY key, MASK mask); void keyUp(KEY key, MASK mask); - void updateMouseState(S32 click, bool down); + void updateMouseState(S32 click, MASK mask, bool down); boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); } -- cgit v1.3 From 08969001e25397cc947b5aa027522d3cc7aa8c53 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 25 Sep 2019 17:54:36 +0300 Subject: SL-6109 Mouse support ready --- indra/llcommon/indra_constants.h | 3 +- indra/llcommon/llkeybind.cpp | 152 ++++++-- indra/llcommon/llkeybind.h | 13 +- indra/llui/llscrolllistcell.cpp | 5 + indra/newview/llagent.cpp | 11 + indra/newview/llagent.h | 1 + indra/newview/llappviewer.cpp | 1 + indra/newview/llfloaterpreference.cpp | 92 +++-- indra/newview/llfloaterpreference.h | 2 +- indra/newview/llkeyconflict.cpp | 131 ++++--- indra/newview/llkeyconflict.h | 10 +- indra/newview/llviewerkeyboard.cpp | 424 ++++++++++++++++++--- indra/newview/llviewerkeyboard.h | 82 +++- indra/newview/llviewerwindow.cpp | 68 ++-- indra/newview/llviewerwindow.h | 3 +- .../skins/default/xui/en/floater_select_key.xml | 16 +- .../default/xui/en/panel_preferences_controls.xml | 10 +- 17 files changed, 813 insertions(+), 211 deletions(-) (limited to 'indra/newview/llviewerwindow.cpp') diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index e763d413e5..ef29e7e5cd 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -61,7 +61,8 @@ enum EMouseClickType{ CLICK_RIGHT, CLICK_BUTTON4, CLICK_BUTTON5, - CLICK_DOUBLELEFT + CLICK_DOUBLELEFT, + CLICK_COUNT // 'size', CLICK_NONE does not counts }; // keys diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index 765084bbf6..0eca289d4b 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -32,20 +32,59 @@ #include "llsdutil.h" LLKeyData::LLKeyData() - : mMouse(CLICK_NONE), mKey(KEY_NONE), mMask(MASK_NONE) + : + mMouse(CLICK_NONE), + mKey(KEY_NONE), + mMask(MASK_NONE), + mIgnoreMasks(false) { } LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask) -: mMouse(mouse), mKey(key), mMask(mask) + : + mMouse(mouse), + mKey(key), + mMask(mask), + mIgnoreMasks(false) +{ +} + +LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, bool ignore_mask) + : + mMouse(mouse), + mKey(key), + mMask(MASK_NONE), + mIgnoreMasks(ignore_mask) +{ +} + +LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) + : + mMouse(mouse), + mKey(key), + mMask(mask), + mIgnoreMasks(ignore_mask) { } LLKeyData::LLKeyData(const LLSD &key_data) { - mMouse = (EMouseClickType)key_data["mouse"].asInteger(); - mKey = key_data["key"].asInteger(); - mMask = key_data["mask"].asInteger(); + if (key_data.has("mouse")) + { + mMouse = (EMouseClickType)key_data["mouse"].asInteger(); + } + if (key_data.has("key")) + { + mKey = key_data["key"].asInteger(); + } + if (key_data.has("ignore_accelerators")) + { + mIgnoreMasks = key_data["ignore_accelerators"]; + } + if (key_data.has("mask")) + { + mMask = key_data["mask"].asInteger(); + } } LLSD LLKeyData::asLLSD() const @@ -53,13 +92,20 @@ LLSD LLKeyData::asLLSD() const LLSD data; data["mouse"] = (LLSD::Integer)mMouse; data["key"] = (LLSD::Integer)mKey; - data["mask"] = (LLSD::Integer)mMask; + if (mIgnoreMasks) + { + data["ignore_accelerators"] = (LLSD::Boolean)mIgnoreMasks; + } + else + { + data["mask"] = (LLSD::Integer)mMask; + } return data; } bool LLKeyData::isEmpty() const { - return mMouse == CLICK_NONE && mKey == KEY_NONE && mMask == MASK_NONE; + return mMouse == CLICK_NONE && mKey == KEY_NONE; } void LLKeyData::reset() @@ -67,6 +113,7 @@ void LLKeyData::reset() mMouse = CLICK_NONE; mKey = KEY_NONE; mMask = MASK_NONE; + mIgnoreMasks = false; } LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) @@ -74,6 +121,7 @@ LLKeyData& LLKeyData::operator=(const LLKeyData& rhs) mMouse = rhs.mMouse; mKey = rhs.mKey; mMask = rhs.mMask; + mIgnoreMasks = rhs.mIgnoreMasks; return *this; } @@ -82,6 +130,7 @@ bool LLKeyData::operator==(const LLKeyData& rhs) if (mMouse != rhs.mMouse) return false; if (mKey != rhs.mKey) return false; if (mMask != rhs.mMask) return false; + if (mIgnoreMasks != rhs.mIgnoreMasks) return false; return true; } @@ -90,6 +139,29 @@ bool LLKeyData::operator!=(const LLKeyData& rhs) if (mMouse != rhs.mMouse) return true; if (mKey != rhs.mKey) return true; if (mMask != rhs.mMask) return true; + if (mIgnoreMasks != rhs.mIgnoreMasks) return true; + return false; +} + +bool LLKeyData::canHandle(const LLKeyData& data) const +{ + if (data.mKey == mKey + && data.mMouse == mMouse + && (mIgnoreMasks || data.mMask == mMask)) + { + return true; + } + return false; +} + +bool LLKeyData::canHandle(EMouseClickType mouse, KEY key, MASK mask) const +{ + if (mouse == mMouse + && key == mKey + && (mIgnoreMasks || mask == mMask)) + { + return true; + } return false; } @@ -167,7 +239,7 @@ bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) { - if (iter->mKey == key && iter->mMask == mask && iter->mMouse == mouse) + if (iter->canHandle(mouse, key, mask)) { return true; } @@ -185,11 +257,34 @@ bool LLKeyBind::canHandleMouse(EMouseClickType mouse, MASK mask) const return canHandle(mouse, KEY_NONE, mask); } -bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask) +bool LLKeyBind::hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const +{ + if (mouse != CLICK_NONE || key != KEY_NONE) + { + for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + { + if (iter->mKey == key + && iter->mMask == mask + && iter->mMouse == mouse + && iter->mIgnoreMasks == ignore) + { + return true; + } + } + } + return false; +} + +bool LLKeyBind::hasKeyData(const LLKeyData& data) const { - if (!canHandle(mouse, key, mask)) + return hasKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks); +} + +bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) +{ + if (!hasKeyData(mouse, key, mask, ignore)) { - mData.push_back(LLKeyData(mouse, key, mask)); + mData.push_back(LLKeyData(mouse, key, mask, ignore)); return true; } return false; @@ -197,7 +292,7 @@ bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask) bool LLKeyBind::addKeyData(const LLKeyData& data) { - if (!canHandle(data.mMouse, data.mKey, data.mMask)) + if (!hasKeyData(data)) { mData.push_back(data); return true; @@ -205,37 +300,48 @@ bool LLKeyBind::addKeyData(const LLKeyData& data) return false; } -void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, U32 index) +void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index) { - if (mouse != CLICK_NONE && key != KEY_NONE && mask != MASK_NONE) + if (mouse != CLICK_NONE || key != KEY_NONE ) { - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + // if both click and key are none, we are inserting a placeholder, we don't want to reset anything + // otherwise reset identical key + for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++) { - if (iter->mKey == key && iter->mMask == mask && iter->mMouse == mouse) + if (iter->mKey == key + && iter->mMouse == mouse + && iter->mIgnoreMasks == ignore + && (iter->mIgnoreMasks || iter->mMask == mask)) { - mData.erase(iter); + iter->reset(); break; } } } if (mData.size() > index) { - mData[index] = LLKeyData(mouse, key, mask); + mData[index] = LLKeyData(mouse, key, mask, ignore); } else { - mData.push_back(LLKeyData(mouse, key, mask)); + mData.push_back(LLKeyData(mouse, key, mask, ignore)); } } void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index) { - for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++) + if (!data.isEmpty()) { - if (iter->mKey == data.mKey && iter->mMask == data.mMask && iter->mMouse == data.mMouse) + for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++) { - mData.erase(iter); - break; + if (iter->mKey == data.mKey + && iter->mMouse == data.mMouse + && iter->mIgnoreMasks == data.mIgnoreMasks + && (iter->mIgnoreMasks || iter->mMask == data.mMask)) + { + iter->reset(); + break; + } } } if (mData.size() > index) diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 481949f275..25179a57f3 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -35,6 +35,8 @@ class LL_COMMON_API LLKeyData public: LLKeyData(); LLKeyData(EMouseClickType mouse, KEY key, MASK mask); + LLKeyData(EMouseClickType mouse, KEY key, bool ignore_mask); + LLKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask); LLKeyData(const LLSD &key_data); LLSD asLLSD() const; @@ -45,9 +47,13 @@ public: bool operator==(const LLKeyData& rhs); bool operator!=(const LLKeyData& rhs); + bool canHandle(const LLKeyData& data) const; + bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const; + EMouseClickType mMouse; KEY mKey; MASK mMask; + bool mIgnoreMasks; }; // One function can bind to multiple Key options @@ -68,10 +74,13 @@ 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; + // these methods enshure there will be no repeats - bool addKeyData(EMouseClickType mouse, KEY key, MASK mask); + bool addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore); bool addKeyData(const LLKeyData& data); - void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, U32 index); + 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(); }; diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 63762ab8b8..0a33ee8878 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -314,6 +314,11 @@ 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);*/ } // Try to draw the entire string diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index be90e623ad..0e43af91df 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -829,6 +829,17 @@ bool LLAgent::enableFlying() return !sitting; } +// static +bool LLAgent::isSitting() +{ + BOOL sitting = FALSE; + if (isAgentAvatarValid()) + { + sitting = gAgentAvatarp->isSitting(); + } + return sitting; +} + void LLAgent::standUp() { setControlFlags(AGENT_CONTROL_STAND_UP); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 5ba1083d8e..a5d37ef496 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -343,6 +343,7 @@ public: static void toggleFlying(); static bool enableFlying(); BOOL canFly(); // Does this parcel allow you to fly? + static bool isSitting(); //-------------------------------------------------------------------- // Voice diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d3067456fa..dde7275e8e 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1451,6 +1451,7 @@ bool LLAppViewer::doFrame() { joystick->scanJoystick(); gKeyboard->scanKeyboard(); + gViewerKeyboard.scanMouse(); } // Update state based on messages, user input, object idle. diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 4a4f66db14..9c706a0d3a 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -166,7 +166,7 @@ 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 IGNORE_MASKS = 32; // For example W (aka Forward) should work regardless of SHIFT being pressed +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; class LLSetKeyBindDialog : public LLModalDialog @@ -176,6 +176,7 @@ public: ~LLSetKeyBindDialog(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quiting); void setParent(LLPanelPreferenceControls* parent, U32 key_mask = DEFAULT_KEY_FILTER); @@ -186,18 +187,23 @@ public: static void onDefault(void* user_data); private: - LLPanelPreferenceControls* mParent; + LLPanelPreferenceControls* pParent; + LLCheckBoxCtrl* pCheckBox; U32 mKeyMask; }; LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key) : LLModalDialog(key), - mParent(NULL), + pParent(NULL), mKeyMask(DEFAULT_KEY_FILTER) { } +LLSetKeyBindDialog::~LLSetKeyBindDialog() +{ +} + //virtual BOOL LLSetKeyBindDialog::postBuild() { @@ -205,15 +211,24 @@ BOOL LLSetKeyBindDialog::postBuild() 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) +{ + pParent = NULL; + LLModalDialog::onClose(app_quiting); +} + void LLSetKeyBindDialog::setParent(LLPanelPreferenceControls* parent, U32 key_mask) { - mParent = parent; + pParent = parent; mKeyMask = key_mask; LLTextBase *text_ctrl = getChild("descritption"); @@ -232,10 +247,10 @@ void LLSetKeyBindDialog::setParent(LLPanelPreferenceControls* parent, U32 key_ma input += getString("keyboard"); } text_ctrl->setTextArg("[INPUT]", input); -} -LLSetKeyBindDialog::~LLSetKeyBindDialog() -{ + 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) @@ -249,10 +264,19 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) return true; } + if (key == KEY_DELETE) + { + if (pParent) + { + pParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); + } + closeFloater(); + return true; + } + // forbidden keys if (key == KEY_NONE || key == KEY_RETURN - || key == KEY_DELETE || key == KEY_BACKSPACE) { return false; @@ -275,9 +299,9 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask) return false; } - else if (mParent) + if (pParent) { - mParent->onSetKeyBind(CLICK_NONE, key, mask); + pParent->onSetKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean()); } closeFloater(); return result; @@ -305,9 +329,9 @@ BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClic && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported && ((mKeyMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) { - if (mParent) + if (pParent) { - mParent->onSetKeyBind(clicktype, KEY_NONE, mask); + pParent->onSetKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean()); } result = TRUE; closeFloater(); @@ -333,9 +357,9 @@ void LLSetKeyBindDialog::onBlank(void* user_data) { LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; // tmp needs 'no key' button - if (self->mParent) + if (self->pParent) { - self->mParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE); + self->pParent->onSetKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false); } self->closeFloater(); } @@ -345,9 +369,9 @@ void LLSetKeyBindDialog::onDefault(void* user_data) { LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data; // tmp needs 'no key' button - if (self->mParent) + if (self->pParent) { - self->mParent->onDefaultKeyBind(); + self->pParent->onDefaultKeyBind(); } self->closeFloater(); } @@ -2972,6 +2996,23 @@ 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)) @@ -2983,14 +3024,14 @@ BOOL LLPanelPreferenceControls::handleHover(S32 x, S32 y, MASK mask) LLSetKeyBindDialog* dialog = LLFloaterReg::showTypedInstance("keybind_dialog", LLSD(), TRUE); if (dialog) { - if (mConflictHandler[mEditingMode].getLoadedMode() == LLKeyConflictHandler::MODE_GENERAL) - { + /*if (mConflictHandler[mEditingMode].getLoadedMode() == LLKeyConflictHandler::MODE_GENERAL) + {*/ dialog->setParent(this, DEFAULT_KEY_FILTER); - } + /*} else { dialog->setParent(this, ALLOW_KEYS | ALLOW_MASK_KEYS); - } + }*/ } } } @@ -3133,10 +3174,6 @@ void LLPanelPreferenceControls::populateControlTable() } } } - - //temp - if (mEditingMode == LLKeyConflictHandler::MODE_GENERAL) - pControlsTable->setEnabled(false); } // Just a workaround to not care about first separator before headers (we can start from random header) @@ -3226,7 +3263,8 @@ void LLPanelPreferenceControls::onModeCommit() regenerateControls(); } -void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask) +// todo: copy onSetKeyBind to interface and inherit from interface +void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask) { LLKeyConflictHandler::EControlTypes control = (LLKeyConflictHandler::EControlTypes)mEditingIndex; @@ -3241,7 +3279,7 @@ void LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MAS if (item && mEditingColumn > 0) { - mConflictHandler[mEditingMode].registerControl(control, mEditingColumn - 1, click, key, mask); + mConflictHandler[mEditingMode].registerControl(control, mEditingColumn - 1, click, key, mask, ignore_mask); LLScrollListCell *cell = item->getColumn(1); cell->setValue(mConflictHandler[mEditingMode].getControlString(control, 0)); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index bce84387ab..1ac0f076d2 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -310,7 +310,7 @@ public: void onListCommit(); void onModeCommit(); - void onSetKeyBind(EMouseClickType click, KEY key, MASK mask); + void onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore_mask); void onRestoreDefaults(); void onDefaultKeyBind(); diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index 0f0129bf68..be0b8fd4ca 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -58,7 +58,6 @@ static const std::string typetostring[LLKeyConflictHandler::CONTROL_NUM_INDICES] "control_wear", "control_movements", "control_moveto", - "control_sit", "control_teleportto", "push_forward", "push_backward", @@ -69,8 +68,9 @@ static const std::string typetostring[LLKeyConflictHandler::CONTROL_NUM_INDICES] "jump", "push_down", //"control_run", - "control_toggle_run", + "toggle_run", "toggle_fly", + "toggle_sit", "stop_moving", "control_camera", "look_up", @@ -103,8 +103,8 @@ static const std::string typetostring[LLKeyConflictHandler::CONTROL_NUM_INDICES] "edit_avatar_move_forward", "edit_avatar_move_backward", "control_mediacontent", - "control_parcel", - "control_media", + "toggle_pause_media", + "toggle_enable_media", "control_voice", "control_toggle_voice", "start_chat", @@ -161,6 +161,10 @@ static const control_enum_t command_to_key = { "stop_moving", LLKeyConflictHandler::CONTROL_STOP }, { "start_chat", LLKeyConflictHandler::CONTROL_START_CHAT }, { "start_gesture", LLKeyConflictHandler::CONTROL_START_GESTURE }, + { "toggle_run", LLKeyConflictHandler::CONTROL_TOGGLE_RUN }, + { "toggle_sit", LLKeyConflictHandler::CONTROL_SIT }, + { "toggle_parcel_media", LLKeyConflictHandler::CONTROL_PAUSE_MEDIA }, + { "toggle_enable_media", LLKeyConflictHandler::CONTROL_ENABLE_MEDIA }, }; @@ -191,6 +195,60 @@ std::string string_from_mask(MASK mask) return res; } +std::string string_from_mouse(EMouseClickType click) +{ + std::string res; + switch (click) + { + case CLICK_LEFT: + res = "LMB"; + break; + case CLICK_MIDDLE: + res = "MMB"; + break; + case CLICK_RIGHT: + res = "RMB"; + break; + case CLICK_BUTTON4: + res = "MB4"; + break; + case CLICK_BUTTON5: + res = "MB5"; + break; + case CLICK_DOUBLELEFT: + res = "Double LMB"; + break; + default: + break; + } + return res; +} + +EMouseClickType mouse_from_string(const std::string& input) +{ + if (input == "LMB") + { + return CLICK_LEFT; + } + if (input == "MMB") + { + return CLICK_MIDDLE; + } + if (input == "RMB") + { + return CLICK_RIGHT; + } + if (input == "MB4") + { + return CLICK_BUTTON4; + } + if (input == "MB5") + { + return CLICK_BUTTON5; + } + return CLICK_NONE; +} + // LLKeyConflictHandler LLKeyConflictHandler::LLKeyConflictHandler() @@ -245,14 +303,14 @@ bool LLKeyConflictHandler::canAssignControl(EControlTypes control_type) return false; } -void LLKeyConflictHandler::registerControl(EControlTypes control_type, U32 index, EMouseClickType mouse, KEY key, MASK mask) +void 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, index); + type_data.mKeyBind.replaceKeyData(mouse, key, mask, ignore_mask, index); mHasUnsavedChanges = true; } @@ -277,45 +335,11 @@ std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata) } else if (keydata.mMask != MASK_NONE) { - LL_ERRS() << "Masks binding without keys is not supported yet" << LL_ENDL; + result = LLKeyboard::stringFromAccelerator(keydata.mMask); } - #ifdef LL_DARWIN - // darwin uses special symbols and doesn't need '+' for masks - if (mMouse != CLICK_NONE && mKey != KEY_NONE) - { - result += " + "; - } - #else - if (keydata.mMouse != CLICK_NONE && !result.empty()) - { - result += " + "; - } - #endif + result += string_from_mouse(keydata.mMouse); - switch (keydata.mMouse) - { - case CLICK_LEFT: - result += "LMB"; - break; - case CLICK_MIDDLE: - result += "MMB"; - break; - case CLICK_RIGHT: - result += "RMB"; - break; - case CLICK_BUTTON4: - result += "MB4"; - break; - case CLICK_BUTTON5: - result += "MB5"; - break; - case CLICK_DOUBLELEFT: - result += "Double LMB"; - break; - default: - break; - } return result; } @@ -339,6 +363,8 @@ void LLKeyConflictHandler::loadFromSettings(const LLViewerKeyboard::KeyMode& ke { KEY key; MASK mask; + EMouseClickType mouse = it->mouse.isProvided() ? mouse_from_string(it->mouse) : CLICK_NONE; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; if (it->key.getValue().empty()) { key = KEY_NONE; @@ -358,7 +384,7 @@ void LLKeyConflictHandler::loadFromSettings(const LLViewerKeyboard::KeyMode& ke LLKeyConflict &type_data = (*destination)[iter->second]; type_data.mAssignable = true; // Don't care about conflict level, all movement and view commands already account for it - type_data.mKeyBind.addKeyData(CLICK_NONE, key, mask); + type_data.mKeyBind.addKeyData(mouse, key, mask, ignore); } } } @@ -418,6 +444,10 @@ void LLKeyConflictHandler::loadFromSettings(EModes load_mode) { mControlsMap.clear(); mDefaultsMap.clear(); + + // E.X. In case we need placeholder keys for conflict resolution. + generatePlaceholders(load_mode); + if (load_mode == MODE_GENERAL) { for (U32 i = 0; i < CONTROL_NUM_INDICES; i++) @@ -463,12 +493,11 @@ void LLKeyConflictHandler::loadFromSettings(EModes load_mode) } else { - mControlsMap = mDefaultsMap; + // mind placeholders + mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); } } mLoadedMode = load_mode; - - generatePlaceholders(); } void LLKeyConflictHandler::saveToSettings() @@ -555,6 +584,8 @@ void LLKeyConflictHandler::saveToSettings() binding.key = LLKeyboard::stringFromKey(data.mKey); } binding.mask = string_from_mask(data.mMask); + binding.mouse.set(string_from_mouse(data.mMouse), true); //set() because 'optional', for compatibility purposes + binding.ignore.set(data.mIgnoreMasks, true); binding.command = getControlName(iter->first); mode.bindings.add(binding); } @@ -711,8 +742,8 @@ void LLKeyConflictHandler::resetToDefaults(EModes mode) else { mControlsMap.clear(); - mControlsMap = mDefaultsMap; - generatePlaceholders(); + generatePlaceholders(mode); + mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end()); } mHasUnsavedChanges = true; @@ -774,7 +805,7 @@ void LLKeyConflictHandler::resetKeyboardBindings() gViewerKeyboard.loadBindingsXML(filename); } -void LLKeyConflictHandler::generatePlaceholders() +void LLKeyConflictHandler::generatePlaceholders(EModes load_mode) { } @@ -784,6 +815,6 @@ void LLKeyConflictHandler::registerTemporaryControl(EControlTypes control_type, LLKeyConflict *type_data = &mControlsMap[control_type]; type_data->mAssignable = false; type_data->mConflictMask = conflict_mask; - type_data->mKeyBind.addKeyData(mouse, key, mask); + type_data->mKeyBind.addKeyData(mouse, key, mask, false); } diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h index 79bd9b8438..7890be1e28 100644 --- a/indra/newview/llkeyconflict.h +++ b/indra/newview/llkeyconflict.h @@ -95,7 +95,6 @@ public: CONTROL_WEAR, CONTROL_MOVEMENTS, // Group control, for visual representation CONTROL_MOVETO, - CONTROL_SIT, CONTROL_TELEPORTTO, CONTROL_FORWARD, CONTROL_BACKWARD, @@ -108,6 +107,7 @@ public: //CONTROL_RUN, CONTROL_TOGGLE_RUN, CONTROL_TOGGLE_FLY, + CONTROL_SIT, CONTROL_STOP, CONTROL_CAMERA, // Group control, for visual representation CONTROL_LOOK_UP, @@ -140,8 +140,8 @@ public: CONTROL_EDIT_AV_MV_FORWARD, CONTROL_EDIT_AV_MV_BACKWARD, CONTROL_MEDIACONTENT, // Group control, for visual representation - CONTROL_PARCEL, // Play pause - CONTROL_MEDIA, // Play stop + CONTROL_PAUSE_MEDIA, // Play pause + CONTROL_ENABLE_MEDIA, // Play stop CONTROL_VOICE, // Keep pressing for it to be ON CONTROL_TOGGLE_VOICE, // Press once to ON/OFF CONTROL_START_CHAT, // Press once to ON/OFF @@ -165,7 +165,7 @@ public: 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); //todo: return conflicts? + void 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); @@ -202,7 +202,7 @@ private: 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 resetKeyboardBindings(); - void generatePlaceholders(); //'headers' for ui and non-assignable values + void generatePlaceholders(EModes load_mode); //E.x. non-assignable values control_map_t mControlsMap; control_map_t mDefaultsMap; diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 878810e0dd..f1a2b037e2 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -603,12 +603,50 @@ void start_gesture( EKeystate s ) } } -void toggle_parcel_media(EKeystate s) +void toggle_run(EKeystate s) { + if (KEYSTATE_DOWN != s) return; + bool run = gAgent.getAlwaysRun(); + if (run) + { + gAgent.clearAlwaysRun(); + gAgent.clearRunning(); + } + else + { + gAgent.setAlwaysRun(); + gAgent.setRunning(); + } + gAgent.sendWalkRun(!run); +} + +void toggle_sit(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return; + if (gAgent.isSitting()) + { + gAgent.standUp(); + } + else + { + gAgent.sitDown(); + } +} + +void toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar +{ + if (KEYSTATE_DOWN != s) return; bool pause = LLViewerMedia::isAnyMediaPlaying(); LLViewerMedia::setAllMediaPaused(pause); } +void toggle_enable_media(EKeystate s) +{ + if (KEYSTATE_DOWN != s) return; + bool pause = LLViewerMedia::isAnyMediaPlaying() || LLViewerMedia::isAnyMediaShowing(); + LLViewerMedia::setAllMediaEnabled(!pause); +} + #define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION); REGISTER_KEYBOARD_ACTION("jump", agent_jump); REGISTER_KEYBOARD_ACTION("push_down", agent_push_down); @@ -650,20 +688,24 @@ REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward) REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving); REGISTER_KEYBOARD_ACTION("start_chat", start_chat); REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture); -REGISTER_KEYBOARD_ACTION("toggle_parcel_media", toggle_parcel_media); +REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run); +REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit); +REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media); +REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media); #undef REGISTER_KEYBOARD_ACTION LLViewerKeyboard::LLViewerKeyboard() { - for (S32 i = 0; i < MODE_COUNT; i++) - { - mBindingCount[i] = 0; - } + resetBindings(); for (S32 i = 0; i < KEY_COUNT; i++) { mKeyHandledByUI[i] = FALSE; - } + } + for (S32 i = 0; i < CLICK_COUNT; i++) + { + mMouseLevel[i] = MOUSE_STATE_SILENT; + } // we want the UI to never see these keys so that they can always control the avatar/camera for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) { @@ -671,7 +713,7 @@ LLViewerKeyboard::LLViewerKeyboard() } } -BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) +BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) const { if (string == "FIRST_PERSON") { @@ -705,6 +747,40 @@ BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode) } } +BOOL LLViewerKeyboard::mouseFromString(const std::string& string, EMouseClickType *mode) const +{ + if (string == "LMB") + { + *mode = CLICK_LEFT; + return TRUE; + } + else if (string == "DLMB") + { + *mode = CLICK_DOUBLELEFT; + return TRUE; + } + else if (string == "MMB") + { + *mode = CLICK_MIDDLE; + return TRUE; + } + else if (string == "MB4") + { + *mode = CLICK_BUTTON4; + return TRUE; + } + else if (string == "MB5") + { + *mode = CLICK_BUTTON5; + return TRUE; + } + else + { + *mode = CLICK_NONE; + return FALSE; + } +} + BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated) { // check for re-map @@ -748,7 +824,7 @@ BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) return gViewerWindow->handleKeyUp(translated_key, translated_mask); } -BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) +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 function_t; @@ -789,11 +865,22 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c } // check for duplicate first and overwrite - for (index = 0; index < mBindingCount[mode]; index++) - { - if (key == mBindings[mode][index].mKey && mask == mBindings[mode][index].mMask) - break; - } + if (ignore) + { + for (index = 0; index < mKeyIgnoreMaskCount[mode]; index++) + { + if (key == mKeyIgnoreMask[mode][index].mKey) + break; + } + } + else + { + for (index = 0; index < mKeyBindingCount[mode]; index++) + { + if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask) + break; + } + } if (index >= MAX_KEY_BINDINGS) { @@ -807,20 +894,102 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c return FALSE; } - mBindings[mode][index].mKey = key; - mBindings[mode][index].mMask = mask; - mBindings[mode][index].mFunction = function; + if (ignore) + { + mKeyIgnoreMask[mode][index].mKey = key; + mKeyIgnoreMask[mode][index].mFunction = function; + + if (index == mKeyIgnoreMaskCount[mode]) + mKeyIgnoreMaskCount[mode]++; + } + else + { + mKeyBindings[mode][index].mKey = key; + mKeyBindings[mode][index].mMask = mask; + mKeyBindings[mode][index].mFunction = function; - if (index == mBindingCount[mode]) - mBindingCount[mode]++; + if (index == mKeyBindingCount[mode]) + mKeyBindingCount[mode]++; + } return TRUE; } +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 function_t; + function_t function = NULL; + + function_t* result = LLKeyboardActionRegistry::getValue(function_name); + if (result) + { + function = *result; + } + + if (!function) + { + LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL; + return FALSE; + } + + // check for duplicate first and overwrite + if (ignore) + { + for (index = 0; index < mMouseIgnoreMaskCount[mode]; index++) + { + if (mouse == mMouseIgnoreMask[mode][index].mMouse) + break; + } + } + else + { + for (index = 0; index < mMouseBindingCount[mode]; index++) + { + if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask) + break; + } + } + + if (index >= MAX_KEY_BINDINGS) + { + LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL; + return FALSE; + } + + if (mode >= MODE_COUNT) + { + LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL; + return FALSE; + } + + if (ignore) + { + mMouseIgnoreMask[mode][index].mMouse = mouse; + mMouseIgnoreMask[mode][index].mFunction = function; + + if (index == mMouseIgnoreMaskCount[mode]) + mMouseIgnoreMaskCount[mode]++; + } + else + { + mMouseBindings[mode][index].mMouse = mouse; + mMouseBindings[mode][index].mMask = mask; + mMouseBindings[mode][index].mFunction = function; + + if (index == mMouseBindingCount[mode]) + mMouseBindingCount[mode]++; + } + + return TRUE; +} + LLViewerKeyboard::KeyBinding::KeyBinding() : key("key"), + mouse("mouse"), mask("mask"), - command("command") + command("command"), + ignore("ignore", false) {} LLViewerKeyboard::KeyMode::KeyMode() @@ -835,12 +1004,20 @@ LLViewerKeyboard::Keys::Keys() edit_avatar("edit_avatar") {} +void LLViewerKeyboard::resetBindings() +{ + for (S32 i = 0; i < MODE_COUNT; i++) + { + mKeyBindingCount[i] = 0; + mKeyIgnoreMaskCount[i] = 0; + mMouseBindingCount[i] = 0; + mMouseIgnoreMaskCount[i] = 0; + } +} + S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename) { - for (S32 i = 0; i < MODE_COUNT; i++) - { - mBindingCount[i] = 0; - } + resetBindings(); S32 binding_count = 0; Keys keys; @@ -870,9 +1047,20 @@ S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, { KEY key; MASK mask; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; LLKeyboard::keyFromString(it->key, &key); LLKeyboard::maskFromString(it->mask, &mask); - bindKey(mode, key, mask, it->command); + bindKey(mode, key, mask, ignore, it->command); + binding_count++; + } + else if (it->mouse.isProvided() && !it->mouse.getValue().empty()) + { + EMouseClickType mouse; + MASK mask; + bool ignore = it->ignore.isProvided() ? it->ignore.getValue() : false; + mouseFromString(it->mouse.getValue(), &mouse); + LLKeyboard::maskFromString(it->mask, &mask); + bindMouse(mode, mouse, mask, ignore, it->command); binding_count++; } } @@ -964,7 +1152,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) } // bind key - if (bindKey(mode, key, mask, function_string)) + if (bindKey(mode, key, mask, false, function_string)) { binding_count++; } @@ -976,7 +1164,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename) } -EKeyboardMode LLViewerKeyboard::getMode() +EKeyboardMode LLViewerKeyboard::getMode() const { if ( gAgentCamera.cameraMouselook() ) { @@ -996,56 +1184,184 @@ EKeyboardMode LLViewerKeyboard::getMode() } } - -// Called from scanKeyboard. -void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) +bool LLViewerKeyboard::scanKey(const LLKeyboardBinding* binding, + S32 binding_count, + KEY key, + MASK mask, + BOOL key_down, + BOOL key_up, + BOOL key_level, + bool repeat) const { - if (LLApp::isExiting()) - { - return; - } - - S32 mode = getMode(); - // Consider keyboard scanning as NOT mouse event. JC - MASK mask = gKeyboard->currentMask(FALSE); - - LLKeyBinding* binding = mBindings[mode]; - S32 binding_count = mBindingCount[mode]; - - - if (mKeyHandledByUI[key]) - { - return; - } - - // don't process key down on repeated keys - BOOL repeat = gKeyboard->getKeyRepeated(key); - for (S32 i = 0; i < binding_count; i++) { - //for (S32 key = 0; key < KEY_COUNT; key++) if (binding[i].mKey == key) { - //if (binding[i].mKey == key && binding[i].mMask == mask) if (binding[i].mMask == mask) { if (key_down && !repeat) { // ...key went down this frame, call function 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; } else if (key_level) { // ...key held down from previous frame // Not windows, just call the function. binding[i].mFunction( KEYSTATE_LEVEL ); + return true; }//if + // Key+Mask combinations are supposed to be unique, so we won't find anything else + return false; }//if - }//for + }//if }//for + return false; +} + +// Called from scanKeyboard. +void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const +{ + if (LLApp::isExiting()) + { + return; + } + + S32 mode = getMode(); + // Consider keyboard scanning as NOT mouse event. JC + MASK mask = gKeyboard->currentMask(FALSE); + + if (mKeyHandledByUI[key]) + { + return; + } + + // 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)) + { + // Nothing found, try ignore list + scanKey(mKeyIgnoreMask[mode], mKeyIgnoreMaskCount[mode], key, MASK_NONE, key_down, key_up, key_level, repeat); + } +} + +BOOL LLViewerKeyboard::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) +{ + BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down); + + if (clicktype != CLICK_NONE) + { + // special case + // if UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set + // handle !down as if we are handling doubleclick + bool override_lmb = (clicktype == CLICK_LEFT + && (mMouseLevel[CLICK_DOUBLELEFT] == MOUSE_STATE_DOWN || mMouseLevel[CLICK_DOUBLELEFT] == MOUSE_STATE_LEVEL)); + + if (override_lmb && !down) + { + // process doubleclick instead + clicktype = CLICK_DOUBLELEFT; + } + + if (override_lmb && down) + { + // else-supress + } + // if UI handled 'down', it should handle 'up' as well + // if we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI + else if (handled && mMouseLevel[clicktype] != MOUSE_STATE_SILENT) + { + // UI handled new 'down' so iterupt whatever state we were in. + mMouseLevel[clicktype] = MOUSE_STATE_UP; + } + else if (down) + { + if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN) + { + // this is repeated hit (mouse does not repeat event until release) + // for now treat rapid clicking like mouse being held + mMouseLevel[clicktype] = MOUSE_STATE_LEVEL; + } + else + { + mMouseLevel[clicktype] = MOUSE_STATE_DOWN; + } + } + else + { + // Released mouse key + mMouseLevel[clicktype] = MOUSE_STATE_UP; + } + } + + return handled; +} + +bool LLViewerKeyboard::scanMouse(const LLMouseBinding *binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const +{ + for (S32 i = 0; i < binding_count; i++) + { + if (binding[i].mMouse == mouse && binding[i].mMask == mask) + { + switch (state) + { + case MOUSE_STATE_DOWN: + binding[i].mFunction(KEYSTATE_DOWN); + break; + case MOUSE_STATE_LEVEL: + binding[i].mFunction(KEYSTATE_LEVEL); + break; + case MOUSE_STATE_UP: + binding[i].mFunction(KEYSTATE_UP); + break; + default: + break; + } + // Key+Mask combinations are supposed to be unique, no need to continue + return true; + } + } + return false; +} + +// todo: this recods key, scanMouse() triggers functions with EKeystate +bool LLViewerKeyboard::scanMouse(EMouseClickType click, EMouseState state) const +{ + bool res = false; + S32 mode = getMode(); + MASK mask = gKeyboard->currentMask(TRUE); + res = scanMouse(mMouseBindings[mode], mMouseBindingCount[mode], click, mask, state); + if (!res) + { + res = scanMouse(mMouseIgnoreMask[mode], mMouseIgnoreMaskCount[mode], click, MASK_NONE, state); + } + return res; +} + +void LLViewerKeyboard::scanMouse() +{ + for (S32 i = 0; i < CLICK_COUNT; i++) + { + if (mMouseLevel[i] != MOUSE_STATE_SILENT) + { + 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 + mMouseLevel[i] = MOUSE_STATE_LEVEL; + } + else if (mMouseLevel[i] == MOUSE_STATE_UP) + { + mMouseLevel[i] = MOUSE_STATE_SILENT; + } + } + } } diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index 2bfe285be4..3ba033509c 100644 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -43,6 +43,27 @@ public: LLKeyFunc mFunction; }; +class LLKeyboardBinding +{ +public: + KEY mKey; + MASK mMask; + bool mIgnoreMask; // whether CTRL/ALT/SHIFT should be checked + + LLKeyFunc mFunction; +}; + +class LLMouseBinding +{ +public: + EMouseClickType mMouse; + MASK mMask; + bool mIgnoreMask; // whether CTRL/ALT/SHIFT should be checked + + LLKeyFunc mFunction; +}; + + typedef enum e_keyboard_mode { MODE_FIRST_PERSON, @@ -53,6 +74,7 @@ typedef enum e_keyboard_mode MODE_COUNT } EKeyboardMode; +class LLWindow; void bind_keyboard_functions(); @@ -64,6 +86,8 @@ public: Mandatory key, mask, command; + Optional mouse; // Note, not mandatory for the sake of backward campatibility + Optional ignore; KeyBinding(); }; @@ -93,24 +117,68 @@ public: 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(); + 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 - BOOL modeFromString(const std::string& string, S32 *mode); // False on failure + void scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const; - void scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level); + // handleMouse() records state, scanMouse() goes through states, scanMouse(click) processes individual saved states after UI is done with them + BOOL handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); + void LLViewerKeyboard::scanMouse(); private: - S32 loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, S32 mode); - BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name); + bool scanKey(const LLKeyboardBinding* binding, + S32 binding_count, + KEY key, + MASK mask, + BOOL key_down, + BOOL key_up, + BOOL key_level, + bool repeat) const; + + enum EMouseState + { + MOUSE_STATE_DOWN, // key down this frame + MOUSE_STATE_LEVEL, // clicked again fast, or never released + MOUSE_STATE_UP, // went up this frame + MOUSE_STATE_SILENT // notified about 'up', do not notify again + }; + bool scanMouse(EMouseClickType click, EMouseState state) const; + bool scanMouse(const LLMouseBinding *binding, + S32 binding_count, + EMouseClickType mouse, + MASK mask, + EMouseState state) const; + + S32 loadBindingMode(const LLViewerKeyboard::KeyMode& keymode, S32 mode); + BOOL bindKey(const S32 mode, const KEY key, const MASK mask, const bool ignore, const std::string& function_name); + BOOL bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const bool ignore, const std::string& function_name); + void resetBindings(); // Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here - S32 mBindingCount[MODE_COUNT]; - LLKeyBinding mBindings[MODE_COUNT][MAX_KEY_BINDINGS]; + // We process specific keys first, then keys that should ignore mask. + // This way with W+ignore defined to 'forward' and with ctrl+W tied to camera, + // pressing undefined Shift+W will do 'forward', yet ctrl+W will do 'camera forward' + // With A defined to 'turn', shift+A defined to strafe, pressing Shift+W+A will do strafe+forward + S32 mKeyBindingCount[MODE_COUNT]; + S32 mKeyIgnoreMaskCount[MODE_COUNT]; + S32 mMouseBindingCount[MODE_COUNT]; + S32 mMouseIgnoreMaskCount[MODE_COUNT]; + LLKeyboardBinding mKeyBindings[MODE_COUNT][MAX_KEY_BINDINGS]; + LLKeyboardBinding mKeyIgnoreMask[MODE_COUNT][MAX_KEY_BINDINGS]; + LLMouseBinding mMouseBindings[MODE_COUNT][MAX_KEY_BINDINGS]; + LLMouseBinding mMouseIgnoreMask[MODE_COUNT][MAX_KEY_BINDINGS]; typedef std::map key_remap_t; key_remap_t mRemapKeys[MODE_COUNT]; std::set mKeysSkippedByUI; BOOL mKeyHandledByUI[KEY_COUNT]; // key processed successfully by UI + + // This is indentical to what llkeyboard does (mKeyRepeated, mKeyLevel, mKeyDown e t c), + // just instead of remembering individually as bools, we record state as enum + EMouseState mMouseLevel[CLICK_COUNT]; // records of key state }; extern LLViewerKeyboard gViewerKeyboard; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2c58295814..bd5370f07f 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -898,6 +898,17 @@ LLViewerWindow::Params::Params() {} +void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask) +{ + if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized()) + { + // If the current tool didn't process the click, we should show + // the pie menu. This can be done by passing the event to the pie + // menu tool. + LLToolPie::getInstance()->handleRightMouseDown(x, y, mask); + } +} + BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down) { const char* buttonname = ""; @@ -996,6 +1007,11 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname)); } + else if (down && clicktype == CLICK_RIGHT) + { + handlePieMenu(x, y, mask); + r = TRUE; + } return r; } @@ -1042,7 +1058,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m return TRUE; } - + if (down && clicktype == CLICK_RIGHT) + { + handlePieMenu(x, y, mask); + return TRUE; + } + // If we got this far on a down-click, it wasn't handled. // Up-clicks, though, are always handled as far as the OS is concerned. BOOL default_rtn = !down; @@ -1061,7 +1082,8 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask mMouseDownTimer.reset(); } BOOL down = TRUE; - return handleAnyMouseClick(window, pos, mask, CLICK_LEFT, down); + //handleMouse() loops back to LLViewerWindow::handleAnyMouseClick + return gViewerKeyboard.handleMouse(window, pos, mask, CLICK_LEFT, down); } BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1069,7 +1091,7 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window, LLCoordGL pos, MASK ma // try handling as a double-click first, then a single-click if that // wasn't handled. BOOL down = TRUE; - if (handleAnyMouseClick(window, pos, mask, CLICK_DOUBLELEFT, down)) + if (gViewerKeyboard.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down)) { return TRUE; } @@ -1083,46 +1105,24 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) mMouseDownTimer.stop(); } BOOL down = FALSE; - return handleAnyMouseClick(window, pos, mask, CLICK_LEFT, down); + return gViewerKeyboard.handleMouse(window, pos, mask, CLICK_LEFT, down); } - - BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { - S32 x = pos.mX; - S32 y = pos.mY; - x = ll_round((F32)x / mDisplayScale.mV[VX]); - y = ll_round((F32)y / mDisplayScale.mV[VY]); - BOOL down = TRUE; - BOOL handle = handleAnyMouseClick(window, pos, mask, CLICK_RIGHT, down); - if (handle) - return handle; - - // *HACK: this should be rolled into the composite tool logic, not - // hardcoded at the top level. - if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized()) - { - // If the current tool didn't process the click, we should show - // the pie menu. This can be done by passing the event to the pie - // menu tool. - LLToolPie::getInstance()->handleRightMouseDown(x, y, mask); - // show_context_menu( x, y, mask ); - } - - return TRUE; + return gViewerKeyboard.handleMouse(window, pos, mask, CLICK_RIGHT, down); } BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - return handleAnyMouseClick(window, pos, mask, CLICK_RIGHT, down); + return gViewerKeyboard.handleMouse(window, pos, mask, CLICK_RIGHT, down); } BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = TRUE; - handleAnyMouseClick(window, pos, mask, CLICK_MIDDLE, down); + gViewerKeyboard.handleMouse(window, pos, mask, CLICK_MIDDLE, down); // Always handled as far as the OS is concerned. return TRUE; @@ -1277,7 +1277,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask) { BOOL down = FALSE; - handleAnyMouseClick(window, pos, mask, CLICK_MIDDLE, down); + gViewerKeyboard.handleMouse(window, pos, mask, CLICK_MIDDLE, down); // Always handled as far as the OS is concerned. return TRUE; @@ -1288,10 +1288,10 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask switch (button) { case 4: - handleAnyMouseClick(window, pos, mask, CLICK_BUTTON4, down); + gViewerKeyboard.handleMouse(window, pos, mask, CLICK_BUTTON4, down); break; case 5: - handleAnyMouseClick(window, pos, mask, CLICK_BUTTON5, down); + gViewerKeyboard.handleMouse(window, pos, mask, CLICK_BUTTON5, down); break; default: break; @@ -1458,7 +1458,8 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) return FALSE; } - return gViewerKeyboard.handleKey(key, mask, repeated); + // remaps, handles ignored cases and returns back to viewer window. + return gViewerKeyboard.handleKey(key, mask, repeated); } BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) @@ -2936,6 +2937,7 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask) { if (mask != MASK_ALT) { + // remaps, handles ignored cases and returns back to viewer window. return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN)); } } diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 5f03685cee..a6365ab328 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -175,8 +175,9 @@ public: void initWorldUI(); void setUIVisibility(bool); bool getUIVisibility(); + void handlePieMenu(S32 x, S32 y, MASK mask); - BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); // // LLWindowCallback interface implementation diff --git a/indra/newview/skins/default/xui/en/floater_select_key.xml b/indra/newview/skins/default/xui/en/floater_select_key.xml index c00b805954..32f091938e 100644 --- a/indra/newview/skins/default/xui/en/floater_select_key.xml +++ b/indra/newview/skins/default/xui/en/floater_select_key.xml @@ -4,7 +4,7 @@ border="false" can_close="false" can_minimize="false" - height="90" + height="116" layout="topleft" name="modal container" width="272"> @@ -31,13 +31,25 @@ Press a key to set your trigger. Allowed input: [INPUT]. + +