From 0e64cc536810e06c1c0d79f5827ad160b45da8c1 Mon Sep 17 00:00:00 2001 From: Louis de Carufel Date: Tue, 14 May 2024 20:44:38 -0400 Subject: [PATCH] Added shader viewer bookmarks and find shortcuts. --- qrenderdoc/Code/Resources.h | 3 +- qrenderdoc/Resources/bookmark_blue.png | Bin 0 -> 594 bytes qrenderdoc/Resources/bookmark_blue@2x.png | Bin 0 -> 2002 bytes qrenderdoc/Resources/resources.qrc | 2 + qrenderdoc/Windows/ShaderViewer.cpp | 211 +++++++++++++++++++--- qrenderdoc/Windows/ShaderViewer.h | 11 ++ qrenderdoc/Windows/ShaderViewer.ui | 23 +++ 7 files changed, 224 insertions(+), 26 deletions(-) create mode 100644 qrenderdoc/Resources/bookmark_blue.png create mode 100644 qrenderdoc/Resources/bookmark_blue@2x.png diff --git a/qrenderdoc/Code/Resources.h b/qrenderdoc/Code/Resources.h index a95c54ecb..92a7dae13 100644 --- a/qrenderdoc/Code/Resources.h +++ b/qrenderdoc/Code/Resources.h @@ -108,7 +108,8 @@ RESOURCE_DEF(topo_tristrip, "topologies/topo_tristrip.svg") \ RESOURCE_DEF(topo_tristrip_adj, "topologies/topo_tristrip_adj.svg") \ RESOURCE_DEF(action, "action.png") \ - RESOURCE_DEF(action_hover, "action_hover.png") + RESOURCE_DEF(action_hover, "action_hover.png") \ + RESOURCE_DEF(bookmark_blue, "bookmark_blue.png") struct Resource { diff --git a/qrenderdoc/Resources/bookmark_blue.png b/qrenderdoc/Resources/bookmark_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..acd8a69133c1e27d76d2c147ea09dfd0113dd7e2 GIT binary patch literal 594 zcmV-Y0Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0q03XK~y+TV;~mj z+U)x;pz`#;SIou#IyMK5Kw|&@|7TzV%Mt)umizvv7C16kTJtbOBtfI!jz{zw4tPZOIAk9g+ zjto;Kyae0K#>T|J%*@EZ$jHc$T_C}*Y|eg$D@UD7Kx!GmI*!)q#nfpO^dz%1EZW6c5ZzQ)(CVh82tOkz~JsJ%CKSieuk?^nn3_=fQ|3@{}y)o z3`Y*W18N2e0!2YK^YE}T=o|4dY+H8#Lo*0~qfyuP;D1vq1BTNlJ_DnP8603NER5jL z*3{<3sTl?s_3aM-|Mws0P6i+b(&944KxhAFP}kyNIJE09Ud=Es7(=+g^lrQVjEsT_ zgOm(A!-<1O@M;DDuor+dNC6l#0=eQ6oD5elTqdX)E6}$;{2vr1KqlN(_yEWS=m4aV gD9s@7|Nnmm0DdIM>^@-L&j0`b07*qoM6N<$f;PhiYXATM literal 0 HcmV?d00001 diff --git a/qrenderdoc/Resources/bookmark_blue@2x.png b/qrenderdoc/Resources/bookmark_blue@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6e93111f6570edd27f092d2ac02c471db98c24 GIT binary patch literal 2002 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!X^24>sLkcg59UmvUF{9L`nl>DSry^7odplSvN z8~cia#N_PM5{0DH^vpb4rT4q{D=B2A*eZpa`WpBaIHzW0dQ=sq23ProBv)l8Tc#-4 z+wpSQR9FE`$W1LtRH(?!$t$+1uvG#ZYz1V4g!Ppaz)DK8ZIv8BHY!B;1}He^7o{qg z>KW)J8<-g?n3?DqniyD`Sn4Pk85kPq8ye{wnCluESecqz85k-+ffCR<1qGX;lr*a# z7dNPNK%T8qMoCG5mA-y?dAVM>v0i>ry1t>MrKP@sk-m|UE>MMTab;dfVufyAu`ZE{1p|w*YQ-UNJPhfFY+}kyxN_sAmB38cdCsN^HTE5i^1xBeXTt6ic1pnl2bihY?Xi}=w)W6SedvvIh$BI zn>(5tI~y9h8ag_=I9WOa#Z26sjg1UkV0vBhlS^|`^GaZPQxJMBaOwp|5-7%OfYt#W z;F4ODS(cjOR+OKs0QR|6CT=I0;xrbjHwCwo%y8?~hdRne9~8?-u?|U5U{PR_0`hG1 z;prK~gXf9VJYYsB0;c%g>k|8cnN7~q#W5tpee3kt9Fb6wC70 zMn}nYaK262&*YZ-6FXsQc^on=vr?kx$_cV@d>~^|h!f~+v^PYWkqF#PbQ=G&7uA`^5JVQpv zeo|-Crz^836tta*>tT~iexFoLQXzKKNh7)_7R|Ey+-v6g1^TUW?x9o-}QH@|DZl|^;CjJ)^bst0Z z{Qm#3u2~*iobmGDXQ_bI_jaz!tywS8&i99P>H{(Dw_09dW`Zihv)F3BRr1ySx@Lay z{?oG?TdoTWPW`(nZ0}NucK&;5fbnM8ScXwA*a zJ#VMK?`KuZ12M0>iA%RfB(*y&4LreHdt|Y@uZkrXh zD-T=t9QmMdaC_c)r?(qt7X0gzWER?&+RmO{C)qsJ&+z>n4TDHH+cBRr zGE#`n{ro#_&RXS)9d9;w{*HZLneevFXG`p^zHh&-FFq8xSu#NT`qwN`IdQ3T{j-}k zS3LJyE}K7P`QmlkB$;hP4Ii$F&`iB~`mUadS_<#S5IW-wv zdh%v0`qA?mmu+6V?BSY~Y$|tlAM3rhx<0sm_U)Z@FGO~DUAkDKXlJ3Fw75s}5ZH-YKt+(>CBnLmaD>?1{70jLo&RFD&CH8O%9){Ea=A--CW38~)Wb z^Iq>=XSL?Uxxxot?#GJ{N9HutSIlpk?884#z2L{vro8rZ;-N9G-!0lCeLv;Q375q$ zt)E|Cxs&DpW3TcF#h0#&S@ Lu6{1-oD!Mwrench@2x.png zoom.png zoom@2x.png + bookmark_blue.png + bookmark_blue@2x.png diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index 68063c33b..62b777a9a 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -838,6 +838,45 @@ void ShaderViewer::debugShader(const ShaderReflection *shader, ResourceId pipeli ui->execForwards->setMenu(forwardsMenu); } + { + QMenu *bookmarkMenu = new QMenu(this); + bookmarkMenu->setToolTipsVisible(true); + + QAction *toggleAction = MakeExecuteAction(tr("Toggle Bookmark"), Icons::bookmark_blue(), + tr("Toggle bookmark on current line"), + QKeySequence(Qt::Key_F2 | Qt::ControlModifier)); + QObject::connect(toggleAction, &QAction::triggered, [this]() { ToggleBookmark(); }); + bookmarkMenu->addAction(toggleAction); + + QAction *nextAction = MakeExecuteAction(tr("Next Bookmark"), Icons::arrow_right(), + tr("Go to next bookmark in the current file"), + QKeySequence(Qt::Key_F2)); + QObject::connect(nextAction, &QAction::triggered, [this]() { NextBookmark(); }); + bookmarkMenu->addAction(nextAction); + + QAction *prevAction = MakeExecuteAction(tr("Previous Bookmark"), Icons::arrow_left(), + tr("Go to previous bookmark in the current file"), + QKeySequence(Qt::Key_F2 | Qt::ShiftModifier)); + QObject::connect(prevAction, &QAction::triggered, [this]() { PreviousBookmark(); }); + bookmarkMenu->addAction(prevAction); + + QAction *clearAction = + MakeExecuteAction(tr("Clear All Bookmarks"), Icons::cross(), + tr("Clear all bookmarks in the current file"), QKeySequence()); + QObject::connect(clearAction, &QAction::triggered, [this]() { ClearAllBookmarks(); }); + bookmarkMenu->addAction(clearAction); + + QObject::connect(bookmarkMenu, &QMenu::aboutToShow, + [this, nextAction, prevAction, clearAction]() { + const bool hasBookmarks = HasBookmarks(); + nextAction->setEnabled(hasBookmarks); + prevAction->setEnabled(hasBookmarks); + clearAction->setEnabled(hasBookmarks); + }); + + ui->bookmark->setMenu(bookmarkMenu); + } + for(ScintillaEdit *edit : m_Scintillas) { edit->setMarginWidthN(1, 20.0 * devicePixelRatioF()); @@ -865,6 +904,16 @@ void ShaderViewer::debugShader(const ShaderReflection *shader, ResourceId pipeli m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F9).toString(), this, [this](QWidget *) { ToggleBreakpointOnInstruction(); }); + // toggle bookmark - Ctrl-F2 + m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F2 | Qt::ControlModifier).toString(), + this, [this](QWidget *) { ToggleBookmark(); }); + // next bookmark - F2 + m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F2).toString(), this, + [this](QWidget *) { NextBookmark(); }); + // previous bookmark - Shift-F2 + m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(Qt::Key_F2 | Qt::ShiftModifier).toString(), + this, [this](QWidget *) { PreviousBookmark(); }); + // event filter to pick up tooltip events ui->constants->installEventFilter(this); ui->accessedResources->installEventFilter(this); @@ -1173,6 +1222,10 @@ void ShaderViewer::debugShader(const ShaderReflection *shader, ResourceId pipeli edit->markerSetBack(BREAKPOINT_MARKER + 1, SCINTILLA_COLOUR(255, 0, 0)); edit->markerDefine(BREAKPOINT_MARKER, SC_MARK_CIRCLE); edit->markerDefine(BREAKPOINT_MARKER + 1, SC_MARK_BACKGROUND); + + // C# Highlight + edit->markerSetBack(BOOKMARK_MARKER, SCINTILLA_COLOUR(51, 153, 255)); + edit->markerDefine(BOOKMARK_MARKER, SC_MARK_BOOKMARK); } } @@ -1489,36 +1542,14 @@ void ShaderViewer::readonly_keyPressed(QKeyEvent *event) if(event->key() == Qt::Key_F && (event->modifiers() & Qt::ControlModifier)) { m_FindReplace->setReplaceMode(false); - - ScintillaEdit *edit = qobject_cast(QObject::sender()); - - if(edit) - { - // if there's a selection, fill the find prompt with that - if(!edit->getSelText().isEmpty()) - { - m_FindReplace->setFindText(QString::fromUtf8(edit->getSelText())); - } - else - { - // otherwise pick the word under the cursor, if there is one - sptr_t scintillaPos = edit->currentPos(); - - sptr_t start = edit->wordStartPosition(scintillaPos, true); - sptr_t end = edit->wordEndPosition(scintillaPos, true); - - QByteArray text = edit->textRange(start, end); - - if(!text.isEmpty()) - m_FindReplace->setFindText(QString::fromUtf8(text)); - } - } - + SetFindTextFromCurrentWord(); on_findReplace_clicked(); } if(event->key() == Qt::Key_F3) { + if(event->modifiers() & Qt::ControlModifier) + SetFindTextFromCurrentWord(); find((event->modifiers() & Qt::ShiftModifier) == 0); } } @@ -1604,6 +1635,31 @@ void ShaderViewer::debug_contextMenu(const QPoint &pos) contextMenu.addAction(&runForwardCursor); contextMenu.addSeparator(); + QAction toggleBookmark(tr("Toggle bookmark here"), this); + QAction nextBookmark(tr("Go to next Bookmark"), this); + QAction prevBookmark(tr("Go to previous Bookmark"), this); + QAction clearBookmarks(tr("Clear all Bookmarks"), this); + + const bool hasBookmarks = HasBookmarks(); + nextBookmark.setEnabled(hasBookmarks); + prevBookmark.setEnabled(hasBookmarks); + clearBookmarks.setEnabled(hasBookmarks); + + toggleBookmark.setShortcut(QKeySequence(Qt::Key_F2 | Qt::ControlModifier)); + nextBookmark.setShortcut(QKeySequence(Qt::Key_F2)); + prevBookmark.setShortcut(QKeySequence(Qt::Key_F2 | Qt::ShiftModifier)); + + QObject::connect(&toggleBookmark, &QAction::triggered, [this] { ToggleBookmark(); }); + QObject::connect(&nextBookmark, &QAction::triggered, [this] { NextBookmark(); }); + QObject::connect(&prevBookmark, &QAction::triggered, [this] { PreviousBookmark(); }); + QObject::connect(&clearBookmarks, &QAction::triggered, [this] { ClearAllBookmarks(); }); + + contextMenu.addAction(&toggleBookmark); + contextMenu.addAction(&nextBookmark); + contextMenu.addAction(&prevBookmark); + contextMenu.addAction(&clearBookmarks); + contextMenu.addSeparator(); + QAction watchExpr(tr("Add Watch Expression"), this); watchExpr.setEnabled(!edit->selectionEmpty()); @@ -6528,3 +6584,108 @@ void ShaderViewer::performReplaceAll() this, tr("Replace all"), tr("%1 replacements made in %2 files").arg(numReplacements).arg(scintillas.count())); } + +void ShaderViewer::ToggleBookmark() +{ + ScintillaEdit *cur = currentScintilla(); + if(!cur) + return; + + sptr_t curLine = cur->lineFromPosition(cur->currentPos()); + + QList &bookmarks = m_Bookmarks[cur]; + if(bookmarks.contains(curLine)) + { + bookmarks.removeOne(curLine); + cur->markerDelete(curLine, BOOKMARK_MARKER); + } + else + { + // Insert new bookmark in numerical order + bookmarks.insert(std::lower_bound(bookmarks.begin(), bookmarks.end(), curLine), curLine); + cur->markerAdd(curLine, BOOKMARK_MARKER); + } +} + +void ShaderViewer::NextBookmark() +{ + ScintillaEdit *cur = currentScintilla(); + if(!cur) + return; + + auto itBookmarks = m_Bookmarks.find(cur); + if(itBookmarks == m_Bookmarks.end() || itBookmarks->empty()) + return; + + sptr_t curLine = cur->lineFromPosition(cur->currentPos()); + auto itNextBookmark = std::upper_bound(itBookmarks->begin(), itBookmarks->end(), curLine); + if(itNextBookmark == itBookmarks->end()) + itNextBookmark = itBookmarks->begin(); + + if(*itNextBookmark != curLine) + cur->gotoLine(*itNextBookmark); +} + +void ShaderViewer::PreviousBookmark() +{ + ScintillaEdit *cur = currentScintilla(); + if(!cur) + return; + + auto itBookmarks = m_Bookmarks.find(cur); + if(itBookmarks == m_Bookmarks.end()) + return; + + sptr_t curLine = cur->lineFromPosition(cur->currentPos()); + auto itPrevBookmark = std::lower_bound(itBookmarks->begin(), itBookmarks->end(), curLine); + if(itPrevBookmark == itBookmarks->begin()) + itPrevBookmark = itBookmarks->end(); + --itPrevBookmark; + + if(*itPrevBookmark != curLine) + cur->gotoLine(*itPrevBookmark); +} + +void ShaderViewer::ClearAllBookmarks() +{ + ScintillaEdit *cur = currentScintilla(); + if(!cur) + return; + + cur->markerDeleteAll(BOOKMARK_MARKER); + m_Bookmarks.remove(cur); +} + +void ShaderViewer::SetFindTextFromCurrentWord() +{ + ScintillaEdit *edit = qobject_cast(QObject::sender()); + + if(edit) + { + // if there's a selection, fill the find prompt with that + if(!edit->getSelText().isEmpty()) + { + m_FindReplace->setFindText(QString::fromUtf8(edit->getSelText())); + } + else + { + // otherwise pick the word under the cursor, if there is one + sptr_t scintillaPos = edit->currentPos(); + + sptr_t start = edit->wordStartPosition(scintillaPos, true); + sptr_t end = edit->wordEndPosition(scintillaPos, true); + + QByteArray text = edit->textRange(start, end); + + if(!text.isEmpty()) + m_FindReplace->setFindText(QString::fromUtf8(text)); + } + } +} + +bool ShaderViewer::HasBookmarks() +{ + ScintillaEdit *cur = currentScintilla(); + auto itBookmarks = m_Bookmarks.find(cur); + return itBookmarks != m_Bookmarks.end() && !itBookmarks->empty(); +} diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h index 1c34b5449..10df04745 100644 --- a/qrenderdoc/Windows/ShaderViewer.h +++ b/qrenderdoc/Windows/ShaderViewer.h @@ -238,6 +238,14 @@ private: ShaderEncoding currentEncoding(); + void ToggleBookmark(); + void NextBookmark(); + void PreviousBookmark(); + void ClearAllBookmarks(); + bool HasBookmarks(); + + void SetFindTextFromCurrentWord(); + QString m_TooltipVarPath; int m_TooltipVarIndex = -1; int m_TooltipMember = -1; @@ -326,9 +334,12 @@ private: QList> m_FindAllResults; + QMap> m_Bookmarks; + static const int CURRENT_MARKER = 0; static const int BREAKPOINT_MARKER = 2; static const int FINISHED_MARKER = 4; + static const int BOOKMARK_MARKER = 6; static const int CURRENT_INDICATOR = 20; static const int FINISHED_INDICATOR = 21; diff --git a/qrenderdoc/Windows/ShaderViewer.ui b/qrenderdoc/Windows/ShaderViewer.ui index 989ab02d4..ad0aee341 100644 --- a/qrenderdoc/Windows/ShaderViewer.ui +++ b/qrenderdoc/Windows/ShaderViewer.ui @@ -319,6 +319,29 @@ + + + + Add, remove or jump to bookmarks in current file + + + Bookmark... + + + + :/bookmark_blue.png:/bookmark_blue.png + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextBesideIcon + + + true + + +