From 5b0bf780cc1d6cbc6c002d74ba97be46be7a666b Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 23 Apr 2016 00:17:33 +0000 Subject: [PATCH] Configurable mouse shortcuts. --- common/lc_application.cpp | 1 + common/lc_glwidget.h | 8 +-- common/lc_model.cpp | 3 ++ common/lc_model.h | 3 +- common/lc_profile.cpp | 3 +- common/lc_profile.h | 3 +- common/lc_shortcuts.cpp | 109 ++++++++++++++++++++++++++++++++++++-- common/lc_shortcuts.h | 23 ++++++++ common/view.cpp | 69 +++++++++++++++++++----- common/view.h | 1 + qt/lc_qglwidget.cpp | 28 +++------- 11 files changed, 206 insertions(+), 45 deletions(-) diff --git a/common/lc_application.cpp b/common/lc_application.cpp index 228ee563..64d5dcc7 100644 --- a/common/lc_application.cpp +++ b/common/lc_application.cpp @@ -305,6 +305,7 @@ bool lcApplication::Initialize(int argc, char* argv[], const char* LibraryInstal gMainWindow = new lcMainWindow(); lcLoadDefaultKeyboardShortcuts(); + lcLoadDefaultMouseShortcuts(); if (!LoadPiecesLibrary(LibPath, LibraryInstallPath, LDrawPath)) { diff --git a/common/lc_glwidget.h b/common/lc_glwidget.h index 224f96ba..744c81fc 100644 --- a/common/lc_glwidget.h +++ b/common/lc_glwidget.h @@ -30,9 +30,7 @@ struct lcInputState { int x; int y; - bool Control; - bool Shift; - bool Alt; + Qt::KeyboardModifiers Modifiers; }; class lcGLWidget @@ -44,9 +42,7 @@ public: mWidget = NULL; mInputState.x = 0; mInputState.y = 0; - mInputState.Control = false; - mInputState.Shift = false; - mInputState.Alt = false; + mInputState.Modifiers = Qt::NoModifier; mContext = new lcContext(); mDeleteContext = true; } diff --git a/common/lc_model.cpp b/common/lc_model.cpp index bb985db9..eee38f35 100644 --- a/common/lc_model.cpp +++ b/common/lc_model.cpp @@ -3434,6 +3434,9 @@ void lcModel::EndMouseTool(lcTool Tool, bool Accept) case LC_TOOL_ZOOM_REGION: break; + + case LC_NUM_TOOLS: + break; } } diff --git a/common/lc_model.h b/common/lc_model.h index 7feffed0..4ef0d075 100644 --- a/common/lc_model.h +++ b/common/lc_model.h @@ -94,7 +94,8 @@ enum lcTool LC_TOOL_PAN, LC_TOOL_ROTATE_VIEW, LC_TOOL_ROLL, - LC_TOOL_ZOOM_REGION + LC_TOOL_ZOOM_REGION, + LC_NUM_TOOLS }; struct lcModelHistoryEntry diff --git a/common/lc_profile.cpp b/common/lc_profile.cpp index 7864a2f8..49f9f6c6 100644 --- a/common/lc_profile.cpp +++ b/common/lc_profile.cpp @@ -63,7 +63,8 @@ lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] = lcProfileEntry("Settings", "CheckUpdates", 1), // LC_PROFILE_CHECK_UPDATES lcProfileEntry("Settings", "ProjectsPath", ""), // LC_PROFILE_PROJECTS_PATH lcProfileEntry("Settings", "PartsLibrary", ""), // LC_PROFILE_PARTS_LIBRARY - lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_SHORTCUTS + lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_KEYBOARD_SHORTCUTS + lcProfileEntry("Settings", "MouseShortcuts"), // LC_PROFILE_MOUSE_SHORTCUTS lcProfileEntry("Settings", "Categories"), // LC_PROFILE_CATEGORIES lcProfileEntry("Settings", "RecentFile1", ""), // LC_PROFILE_RECENT_FILE1 lcProfileEntry("Settings", "RecentFile2", ""), // LC_PROFILE_RECENT_FILE2 diff --git a/common/lc_profile.h b/common/lc_profile.h index bfaf0004..aaa9fc43 100644 --- a/common/lc_profile.h +++ b/common/lc_profile.h @@ -19,7 +19,8 @@ enum LC_PROFILE_KEY LC_PROFILE_CHECK_UPDATES, LC_PROFILE_PROJECTS_PATH, LC_PROFILE_PARTS_LIBRARY, - LC_PROFILE_SHORTCUTS, + LC_PROFILE_KEYBOARD_SHORTCUTS, + LC_PROFILE_MOUSE_SHORTCUTS, LC_PROFILE_CATEGORIES, LC_PROFILE_RECENT_FILE1, LC_PROFILE_RECENT_FILE2, diff --git a/common/lc_shortcuts.cpp b/common/lc_shortcuts.cpp index eef178f2..425c8f05 100644 --- a/common/lc_shortcuts.cpp +++ b/common/lc_shortcuts.cpp @@ -1,12 +1,14 @@ #include "lc_global.h" #include "lc_shortcuts.h" #include "lc_profile.h" +#include "system.h" lcKeyboardShortcuts gKeyboardShortcuts; +lcMouseShortcuts gMouseShortcuts; void lcLoadDefaultKeyboardShortcuts() { - QByteArray Buffer = lcGetProfileBuffer(LC_PROFILE_SHORTCUTS); + QByteArray Buffer = lcGetProfileBuffer(LC_PROFILE_KEYBOARD_SHORTCUTS); QTextStream Stream(Buffer, QIODevice::ReadOnly); if (Buffer.isEmpty() || !gKeyboardShortcuts.Load(Stream)) @@ -20,14 +22,23 @@ void lcSaveDefaultKeyboardShortcuts() gKeyboardShortcuts.Save(Stream); - lcSetProfileBuffer(LC_PROFILE_SHORTCUTS, Buffer); + lcSetProfileBuffer(LC_PROFILE_KEYBOARD_SHORTCUTS, Buffer); } void lcResetDefaultKeyboardShortcuts() { gKeyboardShortcuts.Reset(); - lcRemoveProfileKey(LC_PROFILE_SHORTCUTS); + lcRemoveProfileKey(LC_PROFILE_KEYBOARD_SHORTCUTS); +} + +void lcLoadDefaultMouseShortcuts() +{ + QByteArray Buffer = lcGetProfileBuffer(LC_PROFILE_MOUSE_SHORTCUTS); + QTextStream Stream(Buffer, QIODevice::ReadOnly); + + if (Buffer.isEmpty() || !gMouseShortcuts.Load(Stream)) + gMouseShortcuts.Reset(); } void lcKeyboardShortcuts::Reset() @@ -102,3 +113,95 @@ bool lcKeyboardShortcuts::Load(QTextStream& Stream) return true; } + +void lcMouseShortcuts::Reset() +{ + memset(mShortcuts, 0, sizeof(mShortcuts)); + mShortcuts[LC_TOOL_ROTATE_VIEW].Modifiers = Qt::AltModifier; + mShortcuts[LC_TOOL_ROTATE_VIEW].Button = Qt::LeftButton; + mShortcuts[LC_TOOL_PAN].Modifiers = Qt::AltModifier; + mShortcuts[LC_TOOL_PAN].Button = Qt::MiddleButton; + mShortcuts[LC_TOOL_ZOOM].Modifiers = Qt::AltModifier; + mShortcuts[LC_TOOL_ZOOM].Button = Qt::RightButton; +} + +QString gToolNames[LC_NUM_TOOLS] = +{ + "AddPiece", // LC_TOOL_INSERT + "AddPointLight", // LC_TOOL_LIGHT + "AddSpotLight", // LC_TOOL_SPOTLIGHT + "AddCamera", // LC_TOOL_CAMERA + "Select", // LC_TOOL_SELECT + "Move", // LC_TOOL_MOVE + "Rotate", // LC_TOOL_ROTATE + "Delete", // LC_TOOL_ERASER + "Paint", // LC_TOOL_PAINT + "CameraZoom", // LC_TOOL_ZOOM + "CameraPan", // LC_TOOL_PAN + "CameraOrbit", // LC_TOOL_ROTATE_VIEW + "CameraRoll", // LC_TOOL_ROLL + "CameraZoomRegion" // LC_TOOL_ZOOM_REGION +}; + +LC_CASSERT(sizeof(gToolNames)/sizeof(gToolNames[0]) == LC_NUM_TOOLS); + +bool lcMouseShortcuts::Save(QTextStream& Stream) +{ + for (int ToolIdx = 0; ToolIdx < LC_NUM_TOOLS; ToolIdx++) + { + int ButtonIndex = 0; + for (int Button = mShortcuts[ToolIdx].Button; Button; Button >>= 1) + ButtonIndex++; + + if (!ButtonIndex) + continue; + + Stream << gToolNames[ToolIdx] << QLatin1String("=") << QKeySequence(mShortcuts[ToolIdx].Modifiers | (Qt::Key_0 + ButtonIndex)).toString() << QLatin1String("\n"); + } + + Stream.flush(); + + return true; +} + +bool lcMouseShortcuts::Load(QTextStream& Stream) +{ + memset(mShortcuts, 0, sizeof(mShortcuts)); + + for (QString Line = Stream.readLine(); !Line.isNull(); Line = Stream.readLine()) + { + int Equals = Line.indexOf('='); + + if (Equals == -1) + continue; + + QString Key = Line.left(Equals); + + int ToolIdx; + for (ToolIdx = 0; ToolIdx < LC_NUM_TOOLS; ToolIdx++) + if (gToolNames[ToolIdx] == Key) + break; + + if (ToolIdx == LC_NUM_TOOLS) + continue; + + QKeySequence KeySequence(Line.mid(Equals + 1)); + if (KeySequence.isEmpty()) + continue; + + int Shortcut = KeySequence[0]; + mShortcuts[ToolIdx].Modifiers = (Qt::KeyboardModifier)(Shortcut & Qt::KeyboardModifierMask); + mShortcuts[ToolIdx].Button = (Qt::MouseButton)(1 << (Shortcut & ~Qt::KeyboardModifierMask)); + } + + return true; +} + +lcTool lcMouseShortcuts::GetTool(Qt::MouseButton Button, Qt::KeyboardModifiers Modifiers) const +{ + for (int ToolIdx = 0; ToolIdx < LC_NUM_TOOLS; ToolIdx++) + if (mShortcuts[ToolIdx].Button == Button && mShortcuts[ToolIdx].Modifiers == Modifiers) + return (lcTool)ToolIdx; + + return LC_NUM_TOOLS; +} diff --git a/common/lc_shortcuts.h b/common/lc_shortcuts.h index 58567cf1..e3e12aa0 100644 --- a/common/lc_shortcuts.h +++ b/common/lc_shortcuts.h @@ -2,6 +2,7 @@ #define _LC_SHORTCUTS_H_ #include "lc_commands.h" +#include "lc_model.h" class lcKeyboardShortcuts { @@ -21,4 +22,26 @@ void lcLoadDefaultKeyboardShortcuts(); void lcSaveDefaultKeyboardShortcuts(); void lcResetDefaultKeyboardShortcuts(); +class lcMouseShortcuts +{ +public: + void Reset(); + bool Save(QTextStream& Stream); + bool Load(QTextStream& Stream); + lcTool GetTool(Qt::MouseButton Button, Qt::KeyboardModifiers Modifiers) const; + + struct + { + Qt::KeyboardModifiers Modifiers; + Qt::MouseButton Button; + } + mShortcuts[LC_NUM_TOOLS]; +}; + +extern lcMouseShortcuts gMouseShortcuts; + +void lcLoadDefaultMouseShortcuts(); +void lcSaveDefaultMouseShortcuts(); +void lcResetDefaultMouseShortcuts(); + #endif // _LC_SHORTCUTS_H_ diff --git a/common/view.cpp b/common/view.cpp index 0fb2ca9c..261d5a4d 100644 --- a/common/view.cpp +++ b/common/view.cpp @@ -294,7 +294,7 @@ lcMatrix44 View::GetProjectionMatrix() const LC_CURSOR_TYPE View::GetCursor() const { - if (mTrackTool == LC_TRACKTOOL_SELECT && mInputState.Control) + if (mTrackTool == LC_TRACKTOOL_SELECT && (mInputState.Modifiers & Qt::ControlModifier)) return LC_CURSOR_SELECT_GROUP; const LC_CURSOR_TYPE CursorFromTrackTool[] = @@ -1625,6 +1625,34 @@ lcTool View::GetCurrentTool() const return ToolFromTrackTool[mTrackTool]; } +lcTrackTool View::GetOverrideTrackTool(Qt::MouseButton Button) const +{ + lcTool OverrideTool = gMouseShortcuts.GetTool(Qt::LeftButton, mInputState.Modifiers); + + if (OverrideTool == LC_NUM_TOOLS) + return LC_TRACKTOOL_NONE; + + lcTrackTool TrackToolFromTool[LC_NUM_TOOLS] = + { + LC_TRACKTOOL_INSERT, // LC_TOOL_INSERT + LC_TRACKTOOL_POINTLIGHT, // LC_TOOL_LIGHT + LC_TRACKTOOL_SPOTLIGHT, // LC_TOOL_SPOTLIGHT + LC_TRACKTOOL_CAMERA, // LC_TOOL_CAMERA + LC_TRACKTOOL_SELECT, // LC_TOOL_SELECT + LC_TRACKTOOL_MOVE_XYZ, // LC_TOOL_MOVE + LC_TRACKTOOL_ROTATE_XYZ, // LC_TOOL_ROTATE + LC_TRACKTOOL_ERASER, // LC_TOOL_ERASER + LC_TRACKTOOL_PAINT, // LC_TOOL_PAINT + LC_TRACKTOOL_ZOOM, // LC_TOOL_ZOOM + LC_TRACKTOOL_PAN, // LC_TOOL_PAN + LC_TRACKTOOL_ORBIT_XY, // LC_TOOL_ROTATE_VIEW + LC_TRACKTOOL_ROLL, // LC_TOOL_ROLL + LC_TRACKTOOL_ZOOM_REGION // LC_TOOL_ZOOM_REGION + }; + + return TrackToolFromTool[OverrideTool]; +} + float View::GetOverlayScale() const { lcVector3 OverlayCenter; @@ -2052,6 +2080,9 @@ void View::UpdateTrackTool() case LC_TOOL_ZOOM_REGION: NewTrackTool = LC_TRACKTOOL_ZOOM_REGION; break; + + case LC_NUM_TOOLS: + break; } switch (mDragState) @@ -2137,6 +2168,9 @@ void View::StartTracking(lcTrackButton TrackButton) case LC_TOOL_ZOOM_REGION: break; + + case LC_NUM_TOOLS: + break; } OnUpdateCursor(); @@ -2165,7 +2199,7 @@ void View::StopTracking(bool Accept) { lcArray Objects = FindObjectsInBox(mMouseDownX, mMouseDownY, mInputState.x, mInputState.y); - if (mInputState.Control) + if (mInputState.Modifiers & Qt::ControlModifier) mModel->AddToSelection(Objects); else mModel->SetSelectionAndFocus(Objects, NULL, 0); @@ -2218,6 +2252,9 @@ void View::StopTracking(bool Accept) } } break; + + case LC_NUM_TOOLS: + break; } mTrackButton = LC_TRACKBUTTON_NONE; @@ -2243,9 +2280,11 @@ void View::OnLeftButtonDown() gMainWindow->SetActiveView(this); - if (mInputState.Alt) + lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::LeftButton); + + if (OverrideTool != LC_TRACKTOOL_NONE) { - mTrackTool = LC_TRACKTOOL_ORBIT_XY; + mTrackTool = OverrideTool; OnUpdateCursor(); } else if (mTrackTool == LC_TRACKTOOL_MOVE_XYZ) @@ -2267,7 +2306,7 @@ void View::OnLeftButtonDown() mModel->InsertPieceToolClicked(GetPieceInsertPosition()); - if (!mInputState.Control) + if ((mInputState.Modifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(LC_TOOL_SELECT); UpdateTrackTool(); @@ -2278,7 +2317,7 @@ void View::OnLeftButtonDown() { mModel->PointLightToolClicked(UnprojectPoint(lcVector3((float)mInputState.x, (float)mInputState.y, 0.9f))); - if (!mInputState.Control) + if ((mInputState.Modifiers & Qt::ControlModifier) == 0) gMainWindow->SetTool(LC_TOOL_SELECT); UpdateTrackTool(); @@ -2294,7 +2333,7 @@ void View::OnLeftButtonDown() { lcObjectSection ObjectSection = FindObjectUnderPointer(false); - if (mInputState.Control) + if (mInputState.Modifiers & Qt::ControlModifier) mModel->FocusOrDeselectObject(ObjectSection); else mModel->ClearSelectionAndSetFocus(ObjectSection); @@ -2360,7 +2399,7 @@ void View::OnLeftButtonDoubleClick() lcObjectSection ObjectSection = FindObjectUnderPointer(false); - if (mInputState.Control) + if (mInputState.Modifiers & Qt::ControlModifier) mModel->FocusOrDeselectObject(ObjectSection); else mModel->ClearSelectionAndSetFocus(ObjectSection); @@ -2376,9 +2415,11 @@ void View::OnMiddleButtonDown() gMainWindow->SetActiveView(this); - if (mInputState.Alt) + lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::MiddleButton); + + if (OverrideTool != LC_TRACKTOOL_NONE) { - mTrackTool = LC_TRACKTOOL_PAN; + mTrackTool = OverrideTool; OnUpdateCursor(); StartTracking(LC_TRACKBUTTON_MIDDLE); } @@ -2399,9 +2440,11 @@ void View::OnRightButtonDown() gMainWindow->SetActiveView(this); - if (mInputState.Alt) + lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::RightButton); + + if (OverrideTool != LC_TRACKTOOL_NONE) { - mTrackTool = LC_TRACKTOOL_ZOOM; + mTrackTool = OverrideTool; OnUpdateCursor(); } else if (mTrackTool == LC_TRACKTOOL_MOVE_XYZ) @@ -2785,5 +2828,5 @@ void View::OnMouseMove() void View::OnMouseWheel(float Direction) { - mModel->Zoom(mCamera, (int)((mInputState.Control ? 100 : 10) * Direction)); + mModel->Zoom(mCamera, (int)(((mInputState.Modifiers & Qt::ControlModifier) ? 100 : 10) * Direction)); } diff --git a/common/view.h b/common/view.h index b212bd9d..be0a96fb 100644 --- a/common/view.h +++ b/common/view.h @@ -134,6 +134,7 @@ protected: void UpdateTrackTool(); lcTool GetCurrentTool() const; + lcTrackTool GetOverrideTrackTool(Qt::MouseButton Button) const; float GetOverlayScale() const; void StartTracking(lcTrackButton TrackButton); void StopTracking(bool Accept); diff --git a/qt/lc_qglwidget.cpp b/qt/lc_qglwidget.cpp index b5a0d795..70a665ab 100644 --- a/qt/lc_qglwidget.cpp +++ b/qt/lc_qglwidget.cpp @@ -164,7 +164,7 @@ void lcQGLWidget::keyPressEvent(QKeyEvent *event) { if (isView && event->key() == Qt::Key_Control) { - widget->mInputState.Control = true; + widget->mInputState.Modifiers = event->modifiers(); widget->OnUpdateCursor(); } @@ -175,7 +175,7 @@ void lcQGLWidget::keyReleaseEvent(QKeyEvent *event) { if (isView && event->key() == Qt::Key_Control) { - widget->mInputState.Control = false; + widget->mInputState.Modifiers = event->modifiers(); widget->OnUpdateCursor(); } @@ -188,9 +188,7 @@ void lcQGLWidget::mousePressEvent(QMouseEvent *event) widget->mInputState.x = event->x() * scale; widget->mInputState.y = widget->mHeight - event->y() * scale - 1; - widget->mInputState.Control = (event->modifiers() & Qt::ControlModifier) != 0; - widget->mInputState.Shift = (event->modifiers() & Qt::ShiftModifier) != 0; - widget->mInputState.Alt = (event->modifiers() & Qt::AltModifier) != 0; + widget->mInputState.Modifiers = event->modifiers(); switch (event->button()) { @@ -227,9 +225,7 @@ void lcQGLWidget::mouseReleaseEvent(QMouseEvent *event) widget->mInputState.x = event->x() * scale; widget->mInputState.y = widget->mHeight - event->y() * scale - 1; - widget->mInputState.Control = (event->modifiers() & Qt::ControlModifier) != 0; - widget->mInputState.Shift = (event->modifiers() & Qt::ShiftModifier) != 0; - widget->mInputState.Alt = (event->modifiers() & Qt::AltModifier) != 0; + widget->mInputState.Modifiers = event->modifiers(); switch (event->button()) { @@ -266,9 +262,7 @@ void lcQGLWidget::mouseDoubleClickEvent(QMouseEvent *event) widget->mInputState.x = event->x() * scale; widget->mInputState.y = widget->mHeight - event->y() * scale - 1; - widget->mInputState.Control = (event->modifiers() & Qt::ControlModifier) != 0; - widget->mInputState.Shift = (event->modifiers() & Qt::ShiftModifier) != 0; - widget->mInputState.Alt = (event->modifiers() & Qt::AltModifier) != 0; + widget->mInputState.Modifiers = event->modifiers(); switch (event->button()) { @@ -286,9 +280,7 @@ void lcQGLWidget::mouseMoveEvent(QMouseEvent *event) widget->mInputState.x = event->x() * scale; widget->mInputState.y = widget->mHeight - event->y() * scale - 1; - widget->mInputState.Control = (event->modifiers() & Qt::ControlModifier) != 0; - widget->mInputState.Shift = (event->modifiers() & Qt::ShiftModifier) != 0; - widget->mInputState.Alt = (event->modifiers() & Qt::AltModifier) != 0; + widget->mInputState.Modifiers = event->modifiers(); widget->OnMouseMove(); } @@ -305,9 +297,7 @@ void lcQGLWidget::wheelEvent(QWheelEvent *event) widget->mInputState.x = event->x() * scale; widget->mInputState.y = widget->mHeight - event->y() * scale - 1; - widget->mInputState.Control = (event->modifiers() & Qt::ControlModifier) != 0; - widget->mInputState.Shift = (event->modifiers() & Qt::ShiftModifier) != 0; - widget->mInputState.Alt = (event->modifiers() & Qt::AltModifier) != 0; + widget->mInputState.Modifiers = event->modifiers(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)) mWheelAccumulator += event->angleDelta().y() / 8; @@ -362,9 +352,7 @@ void lcQGLWidget::dragMoveEvent(QDragMoveEvent *event) widget->mInputState.x = event->pos().x() * scale; widget->mInputState.y = widget->mHeight - event->pos().y() * scale - 1; - widget->mInputState.Control = (event->keyboardModifiers() & Qt::ControlModifier) != 0; - widget->mInputState.Shift = (event->keyboardModifiers() & Qt::ShiftModifier) != 0; - widget->mInputState.Alt = (event->keyboardModifiers() & Qt::AltModifier) != 0; + widget->mInputState.Modifiers = event->keyboardModifiers(); widget->OnMouseMove();