From e32580d28783e50ac2868b87c7e6dd344879e67b Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 29 May 2025 17:56:05 -0400 Subject: [PATCH 1/9] add logspaced colorbar support --- Palette.H | 3 ++- Palette.cpp | 29 ++++++++++++++++++++++++----- PltApp.H | 1 + PltApp.cpp | 27 +++++++++++++++++++++++++++ PltAppState.H | 5 +++++ PltAppState.cpp | 2 ++ 6 files changed, 61 insertions(+), 6 deletions(-) diff --git a/Palette.H b/Palette.H index 9b35f38..b2ae388 100644 --- a/Palette.H +++ b/Palette.H @@ -72,13 +72,14 @@ class Palette { PaletteType GetPaletteType() { return paletteType; } amrex::Vector GetTransferArray() { return transferArray; } int ReadSeqPalette(const string &fileName, bool bRedraw = true); - void DrawPalette(Real palMin, Real palMax, const string &numberFormat); + void DrawPalette(Real palMin, Real palMax, const string &numberFormat, bool logScale = false); void SetWindow(Window drawPaletteHere); void SetWindowPalette(const string &palName, Window newPalWindow, bool bRedraw = true); void ChangeWindowPalette(const string &palName, Window newPalWindow); void ExposePalette(); void RedrawPalette(); + void RedrawPalette(bool logScale); void SetReserveSystemColors(int reservesystemcolors); void SetFormat(const string &newFormat); Colormap GetColormap() const { return colmap; } diff --git a/Palette.cpp b/Palette.cpp index d38bb7c..d1a6487 100644 --- a/Palette.cpp +++ b/Palette.cpp @@ -10,6 +10,7 @@ #include #include +#include using std::cout; using std::cerr; using std::endl; @@ -173,9 +174,14 @@ void Palette::RedrawPalette() { DrawPalette(pmin, pmax, defaultFormat); // use defaults } +// ------------------------------------------------------------------- +void Palette::RedrawPalette(bool logScale) { + DrawPalette(pmin, pmax, defaultFormat, logScale); // use defaults with log scale +} + // ------------------------------------------------------------------- -void Palette::DrawPalette(Real palMin, Real palMax, const string &numberFormat) { +void Palette::DrawPalette(Real palMin, Real palMax, const string &numberFormat, bool logScale) { int i, cy, palOffsetY(14); XWindowAttributes winAttribs; Display *display(gaPtr->PDisplay()); @@ -329,10 +335,23 @@ void Palette::DrawPalette(Real palMin, Real palMax, const string &numberFormat) char palString[128]; for(i = 0; i < dataList.size(); ++i) { XSetForeground(display, gc, AVWhitePixel()); - dataList[i] = palMin + (dataList.size() - 1 - i) * - (palMax - palMin) / (dataList.size() - 1); - if(i == 0) { - dataList[i] = palMax; // to avoid roundoff + if(logScale && palMin > 0.0 && palMax > 0.0) { + // Log scale: interpolate in log space + Real logMin = std::log10(palMin); + Real logMax = std::log10(palMax); + Real logVal = logMin + (dataList.size() - 1 - i) * + (logMax - logMin) / (dataList.size() - 1); + dataList[i] = std::pow(10.0, logVal); + if(i == 0) { + dataList[i] = palMax; // to avoid roundoff + } + } else { + // Linear scale (original behavior) + dataList[i] = palMin + (dataList.size() - 1 - i) * + (palMax - palMin) / (dataList.size() - 1); + if(i == 0) { + dataList[i] = palMax; // to avoid roundoff + } } sprintf(palString, numberFormat.c_str(), dataList[i]); XDrawString(display, palPixmap, gc, palWidth + 4, diff --git a/PltApp.H b/PltApp.H index 9cabf91..d197c47 100644 --- a/PltApp.H +++ b/PltApp.H @@ -249,6 +249,7 @@ private: void DirtyFrames(); void DoRubberBanding(Widget, XtPointer, XtPointer); void DoBoxesButton(Widget, XtPointer, XtPointer); + void DoLogScaleButton(Widget, XtPointer, XtPointer); void DoCGSmoothing(Widget, XtPointer, XtPointer); void DoCGShowBody(Widget, XtPointer, XtPointer); void DoAnimBackStep(); diff --git a/PltApp.cpp b/PltApp.cpp index 1b1cd4b..978c6e7 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -26,6 +26,7 @@ #include #include +#include #include @@ -1060,6 +1061,18 @@ void PltApp::PltAppInit(bool bSubVolume) { XmStringFree(label_str); AddStaticCallback(wid, XmNvalueChangedCallback, &PltApp::DoBoxesButton); + // Toggle log scale colorbar + label_str = XmStringCreateSimple(const_cast("l")); + wid = XtVaCreateManagedWidget("Log Scale", + xmToggleButtonGadgetClass, wMenuPulldown, + XmNmnemonic, 'L', + XmNset, pltAppState->GetLogScale(), + XmNaccelerator, "L", + XmNacceleratorText, label_str, + NULL); + XmStringFree(label_str); + AddStaticCallback(wid, XmNvalueChangedCallback, &PltApp::DoLogScaleButton); + if(amrData.CartGrid()) { // cart grid smoothing label_str = XmStringCreateSimple(const_cast("s")); @@ -3370,6 +3383,20 @@ void PltApp::DoBoxesButton(Widget, XtPointer, XtPointer) { } +// ------------------------------------------------------------------- +void PltApp::DoLogScaleButton(Widget, XtPointer, XtPointer) { + if(animating2d) { + ResetAnimation(); + DirtyFrames(); + } + pltAppState->SetLogScale( ! pltAppState->GetLogScale()); + pltPaletteptr->RedrawPalette(pltAppState->GetLogScale()); + for(int np(0); np < Amrvis::NPLANES; ++np) { + amrPicturePtrArray[np]->DoExposePicture(); + } +} + + // ------------------------------------------------------------------- void PltApp::DoCGSmoothing(Widget, XtPointer, XtPointer) { if(animating2d) { diff --git a/PltAppState.H b/PltAppState.H index 2fa98b3..6516dc3 100644 --- a/PltAppState.H +++ b/PltAppState.H @@ -81,6 +81,10 @@ public: bool GetCGSmoothing() const { return cgSmoothing; } void SetCGSmoothing(bool smoothing) { cgSmoothing = smoothing; } + // ------------------------ log scale + bool GetLogScale() const { return logScale; } + void SetLogScale(bool useLogScale) { logScale = useLogScale; } + // ------------------------ number format string GetFormatString() const { return formatString; } void SetFormatString(const string &newformat) { formatString = newformat; } @@ -139,6 +143,7 @@ private: int currentDerivedNumber; bool showBoxes; bool cgSmoothing; + bool logScale; amrex::Amrvis::ContourType currentContourType; int nContours; amrex::Amrvis::MinMaxRangeType currentMinMaxType; diff --git a/PltAppState.cpp b/PltAppState.cpp index 3fba850..48f5625 100644 --- a/PltAppState.cpp +++ b/PltAppState.cpp @@ -68,6 +68,7 @@ PltAppState::PltAppState(int numFrames, int numDerived) } } cgSmoothing = false; + logScale = false; } @@ -88,6 +89,7 @@ PltAppState &PltAppState::operator=(const PltAppState &rhs) { currentDerivedNumber = rhs.currentDerivedNumber; showBoxes = rhs.showBoxes; cgSmoothing = rhs.cgSmoothing; + logScale = rhs.logScale; currentContourType = rhs.currentContourType; nContours = rhs.nContours; currentMinMaxType = rhs.currentMinMaxType; From 18ef34d8cbae9ebd13f3d0063530d1ee7b4359cf Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 29 May 2025 17:56:54 -0400 Subject: [PATCH 2/9] comment out XGrabServer --- PltApp.H | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PltApp.H b/PltApp.H index d197c47..1ec7920 100644 --- a/PltApp.H +++ b/PltApp.H @@ -349,7 +349,7 @@ class AVXGrab { public: AVXGrab(Display *display) : bIsGrabbed(true), cachedDisplay(display) { XSync(cachedDisplay, False); - XGrabServer(display); + //XGrabServer(display); XSync(cachedDisplay, False); } From 263c6b3e9442fd6bf67701e2ff2ee9e8c3d74e27 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 29 May 2025 20:50:51 -0400 Subject: [PATCH 3/9] fix log-scaling data color mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The log scale toggle was previously only updating the colorbar labels but not the actual data-to-color mapping. This fix implements logarithmic transformation of data values before color mapping when log scaling is enabled. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- AmrPicture.H | 3 ++- AmrPicture.cpp | 50 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/AmrPicture.H b/AmrPicture.H index 851f609..cad844c 100644 --- a/AmrPicture.H +++ b/AmrPicture.H @@ -143,7 +143,8 @@ class AmrPicture { void CreateImage(const amrex::FArrayBox &fab, unsigned char *imagedata, int datasizeh, int datasizev, Real globalMin, Real globalMax, Palette *palptr, - const amrex::FArrayBox *vfracFab, const Real vfeps); + const amrex::FArrayBox *vfracFab, const Real vfeps, + bool logScale = false); void CreateScaledImage(XImage **ximage, int scale, unsigned char *imagedata, unsigned char *scaledimagedata, diff --git a/AmrPicture.cpp b/AmrPicture.cpp index 3373f72..1c6bea6 100644 --- a/AmrPicture.cpp +++ b/AmrPicture.cpp @@ -614,7 +614,7 @@ void AmrPicture::APChangeContour(Amrvis::ContourType prevCType) { CreateImage(*(sliceFab[iLevel]), imageData[iLevel], dataSizeH[iLevel], dataSizeV[iLevel], minUsing, maxUsing, palPtr, - vffp, vfeps); + vffp, vfeps, pltAppStatePtr->GetLogScale()); bool bCreateMask(iLevel == minDrawnLevel); CreateScaledImage(&(xImageArray[iLevel]), pltAppStatePtr->CurrentScale() * amrex::CRRBetweenLevels(iLevel, maxAllowableLevel, @@ -880,7 +880,7 @@ void AmrPicture::APMakeImages(Palette *palptr) { } CreateImage(*(sliceFab[iLevel]), imageData[iLevel], dataSizeH[iLevel], dataSizeV[iLevel], - minUsing, maxUsing, palPtr, vffp, vfeps); + minUsing, maxUsing, palPtr, vffp, vfeps, pltAppStatePtr->GetLogScale()); bool bCreateMask(iLevel == minDrawnLevel); CreateScaledImage(&(xImageArray[iLevel]), pltAppStatePtr->CurrentScale() * amrex::CRRBetweenLevels(iLevel, maxAllowableLevel, @@ -904,15 +904,29 @@ void AmrPicture::APMakeImages(Palette *palptr) { void AmrPicture::CreateImage(const FArrayBox &fab, unsigned char *imagedata, int datasizeh, int datasizev, Real globalMin, Real globalMax, Palette *palptr, - const FArrayBox *vfracFab, const Real vfeps) + const FArrayBox *vfracFab, const Real vfeps, + bool logScale) { int jdsh, jtmp1; int dIndex, iIndex; Real oneOverGDiff; - if((globalMax - globalMin) < FLT_MIN) { - oneOverGDiff = 0.0; + Real logGlobalMin, logGlobalMax; + bool useLogScale = logScale && globalMin > 0.0 && globalMax > 0.0; + + if(useLogScale) { + logGlobalMin = std::log10(globalMin); + logGlobalMax = std::log10(globalMax); + if((logGlobalMax - logGlobalMin) < FLT_MIN) { + oneOverGDiff = 0.0; + } else { + oneOverGDiff = 1.0 / (logGlobalMax - logGlobalMin); + } } else { - oneOverGDiff = 1.0 / (globalMax - globalMin); + if((globalMax - globalMin) < FLT_MIN) { + oneOverGDiff = 0.0; + } else { + oneOverGDiff = 1.0 / (globalMax - globalMin); + } } const Real *dataPoint = fab.dataPtr(); bool bCartGrid(dataServicesPtr->AmrDataRef().CartGrid()); @@ -943,9 +957,14 @@ void AmrPicture::CreateImage(const FArrayBox &fab, unsigned char *imagedata, } else if(dPoint < globalMin) { // clip imagedata[iIndex] = paletteStart; } else { - imagedata[iIndex] = (unsigned char) - ((((dPoint - globalMin) * oneOverGDiff) * csm1) ); - // ^^^^^^^^^^^^^^^^^^ Real data + if(useLogScale && dPoint > 0.0) { + Real logDPoint = std::log10(dPoint); + imagedata[iIndex] = (unsigned char) + ((((logDPoint - logGlobalMin) * oneOverGDiff) * csm1) ); + } else { + imagedata[iIndex] = (unsigned char) + ((((dPoint - globalMin) * oneOverGDiff) * csm1) ); + } imagedata[iIndex] += paletteStart; } } @@ -966,9 +985,14 @@ void AmrPicture::CreateImage(const FArrayBox &fab, unsigned char *imagedata, } else if(dPoint < globalMin) { // clip imagedata[iIndex] = paletteStart; } else { - imagedata[iIndex] = (unsigned char) - ((((dPoint - globalMin) * oneOverGDiff) * csm1) ); - // ^^^^^^^^^^^^^^^^^^ Real data + if(useLogScale && dPoint > 0.0) { + Real logDPoint = std::log10(dPoint); + imagedata[iIndex] = (unsigned char) + ((((logDPoint - logGlobalMin) * oneOverGDiff) * csm1) ); + } else { + imagedata[iIndex] = (unsigned char) + ((((dPoint - globalMin) * oneOverGDiff) * csm1) ); + } imagedata[iIndex] += paletteStart; } if(dVFPoint < vfeps) { // set to body color @@ -1686,7 +1710,7 @@ void AmrPicture::CreateFrames(Amrvis::AnimDirection direction) { } CreateImage(imageFab, frameImageData, dataSizeH[maxDrawnLevel], dataSizeV[maxDrawnLevel], - minUsing, maxUsing, palPtr, vffp, vfeps); + minUsing, maxUsing, palPtr, vffp, vfeps, pltAppStatePtr->GetLogScale()); // this cannot be deleted because it belongs to the XImage unsigned char *frameScaledImageData; From c2d0198e179b1f77fad3aace838d4224d5ab7f0e Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 29 May 2025 21:10:04 -0400 Subject: [PATCH 4/9] recompute pixmap on log-scale toggle --- PltApp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PltApp.cpp b/PltApp.cpp index 978c6e7..72719a8 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -3392,7 +3392,7 @@ void PltApp::DoLogScaleButton(Widget, XtPointer, XtPointer) { pltAppState->SetLogScale( ! pltAppState->GetLogScale()); pltPaletteptr->RedrawPalette(pltAppState->GetLogScale()); for(int np(0); np < Amrvis::NPLANES; ++np) { - amrPicturePtrArray[np]->DoExposePicture(); + amrPicturePtrArray[np]->APMakeImages(pltPaletteptr); } } From 0876fcbd97767671d59c76f27fb621119c687dd1 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 29 May 2025 23:24:56 -0400 Subject: [PATCH 5/9] clear selection on ESC press --- PltApp.H | 2 ++ PltApp.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/PltApp.H b/PltApp.H index 1ec7920..66e1e91 100644 --- a/PltApp.H +++ b/PltApp.H @@ -248,6 +248,7 @@ private: void ShowFrame(); void DirtyFrames(); void DoRubberBanding(Widget, XtPointer, XtPointer); + void DoGlobalKeyPress(Widget, XtPointer, XtPointer); void DoBoxesButton(Widget, XtPointer, XtPointer); void DoLogScaleButton(Widget, XtPointer, XtPointer); void DoCGSmoothing(Widget, XtPointer, XtPointer); @@ -275,6 +276,7 @@ private: void DoUserMax(Widget, XtPointer, XtPointer); void DoOpenPalFile(Widget, XtPointer, XtPointer); void DoSubregion(Widget, XtPointer, XtPointer); + void ClearSelection(); void DoInfoButton(Widget, XtPointer, XtPointer); void DoOutput(Widget, XtPointer, XtPointer); void DoCreatePSFile(Widget, XtPointer, XtPointer); diff --git a/PltApp.cpp b/PltApp.cpp index 72719a8..c5e510c 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -1668,6 +1668,9 @@ void PltApp::PltAppInit(bool bSubVolume) { XtManageChild(wPlotArea); XtPopup(wAmrVisTopLevel, XtGrabNone); + // Add global ESC key handler + AddStaticEventHandler(wAmrVisTopLevel, KeyPressMask, &PltApp::DoGlobalKeyPress); + pltPaletteptr->SetWindow(XtWindow(wPalArea)); pltPaletteptr->SetWindowPalette(palFilename, XtWindow(wPalArea), false); pltPaletteptr->SetWindowPalette(palFilename, XtWindow(wPlotArea), false); @@ -2363,7 +2366,39 @@ void PltApp::DoSubregion(Widget, XtPointer, XtPointer) { #endif } // end DoSubregion + +// ------------------------------------------------------------------- +void PltApp::ClearSelection() { + // Clear the selection by setting the selectionBox to an empty state + selectionBox.setSmall(Amrvis::XDIR, 0); + selectionBox.setBig(Amrvis::XDIR, 0); +#if (BL_SPACEDIM != 1) + selectionBox.setSmall(Amrvis::YDIR, 0); + selectionBox.setBig(Amrvis::YDIR, 0); +#endif +#if (BL_SPACEDIM == 3) + selectionBox.setSmall(Amrvis::ZDIR, 0); + selectionBox.setBig(Amrvis::ZDIR, 0); + // Clear the 3D cutting coordinates + for(int np = 0; np < Amrvis::NPLANES; ++np) { + startcutX[np] = 0; + startcutY[np] = 0; + finishcutX[np] = 0; + finishcutY[np] = 0; + // Clear subcut by setting all coordinates to 0 (invalid region) + amrPicturePtrArray[np]->SetSubCut(0, 0, 0, 0); + } +#endif + + // Clear the 2D selection region for all planes by setting invalid coordinates + for(int np = 0; np < Amrvis::NPLANES; ++np) { + amrPicturePtrArray[np]->SetRegion(0, 0, 0, 0); + amrPicturePtrArray[np]->DoExposePicture(); + } +} + + // ------------------------------------------------------------------- void PltApp::DoDatasetButton(Widget, XtPointer, XtPointer) { #if (BL_SPACEDIM == 1) @@ -4095,6 +4130,17 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) case NoExpose: break; + case KeyPress: { + KeySym keysym = XLookupKeysym(&nextEvent.xkey, 0); + if(keysym == XK_Escape) { + // ESC key pressed - clear selection and exit rubber banding + avxGrab.ExplicitUngrab(); + ClearSelection(); + return; + } + } + break; + default: break; } // end switch @@ -4441,6 +4487,17 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) } // end DoRubberBanding +// ------------------------------------------------------------------- +void PltApp::DoGlobalKeyPress(Widget, XtPointer, XtPointer call_data) { + XKeyPressedEvent *event = (XKeyPressedEvent *) call_data; + KeySym keysym = XLookupKeysym(event, 0); + if(keysym == XK_Escape) { + // ESC key pressed - clear any existing selection + ClearSelection(); + } +} + + // ------------------------------------------------------------------- void PltApp::DoExposePalette(Widget, XtPointer, XtPointer) { pltPaletteptr->ExposePalette(); From 03521a72ce66aac6754c0aa0c453d2c2f3ce4a41 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Thu, 29 May 2025 23:50:32 -0400 Subject: [PATCH 6/9] attempt to fix ESC key handling --- PltApp.H | 1 + PltApp.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/PltApp.H b/PltApp.H index 66e1e91..37a894b 100644 --- a/PltApp.H +++ b/PltApp.H @@ -139,6 +139,7 @@ public: private: Widget wTopLevel; + Widget wMainArea; Widget wScrollArea[amrex::Amrvis::NPLANES], wPlotPlane[amrex::Amrvis::NPLANES]; amrex::Vector wRangeRadioButton; Widget wFileRangeCheckBox; diff --git a/PltApp.cpp b/PltApp.cpp index c5e510c..eef1497 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -835,11 +835,15 @@ void PltApp::PltAppInit(bool bSubVolume) { cursor = XCreateFontCursor(display, XC_left_ptr); // No need to store these widgets in the class after this function is called. - Widget wMainArea, wPalFrame, wPlotFrame, wPalForm; + Widget wPalFrame, wPlotFrame, wPalForm; wMainArea = XtVaCreateManagedWidget("MainArea", xmFormWidgetClass, wAmrVisTopLevel, + XmNkeyboardFocusPolicy, XmPOINTER, NULL); + + // Add global ESC key handler to main area which can receive keyboard focus + AddStaticEventHandler(wMainArea, KeyPressMask, &PltApp::DoGlobalKeyPress); // ------------------------------- menu bar Widget wMenuBar, wMenuPulldown, wid, wCascade; @@ -1668,9 +1672,6 @@ void PltApp::PltAppInit(bool bSubVolume) { XtManageChild(wPlotArea); XtPopup(wAmrVisTopLevel, XtGrabNone); - // Add global ESC key handler - AddStaticEventHandler(wAmrVisTopLevel, KeyPressMask, &PltApp::DoGlobalKeyPress); - pltPaletteptr->SetWindow(XtWindow(wPalArea)); pltPaletteptr->SetWindowPalette(palFilename, XtWindow(wPalArea), false); pltPaletteptr->SetWindowPalette(palFilename, XtWindow(wPlotArea), false); From 0a8188841abd61a048c8747de2aa5a625be50b69 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Fri, 6 Jun 2025 12:40:32 -0400 Subject: [PATCH 7/9] Revert last two commits: ESC key handling changes --- PltApp.H | 3 --- PltApp.cpp | 60 +----------------------------------------------------- 2 files changed, 1 insertion(+), 62 deletions(-) diff --git a/PltApp.H b/PltApp.H index 37a894b..1ec7920 100644 --- a/PltApp.H +++ b/PltApp.H @@ -139,7 +139,6 @@ public: private: Widget wTopLevel; - Widget wMainArea; Widget wScrollArea[amrex::Amrvis::NPLANES], wPlotPlane[amrex::Amrvis::NPLANES]; amrex::Vector wRangeRadioButton; Widget wFileRangeCheckBox; @@ -249,7 +248,6 @@ private: void ShowFrame(); void DirtyFrames(); void DoRubberBanding(Widget, XtPointer, XtPointer); - void DoGlobalKeyPress(Widget, XtPointer, XtPointer); void DoBoxesButton(Widget, XtPointer, XtPointer); void DoLogScaleButton(Widget, XtPointer, XtPointer); void DoCGSmoothing(Widget, XtPointer, XtPointer); @@ -277,7 +275,6 @@ private: void DoUserMax(Widget, XtPointer, XtPointer); void DoOpenPalFile(Widget, XtPointer, XtPointer); void DoSubregion(Widget, XtPointer, XtPointer); - void ClearSelection(); void DoInfoButton(Widget, XtPointer, XtPointer); void DoOutput(Widget, XtPointer, XtPointer); void DoCreatePSFile(Widget, XtPointer, XtPointer); diff --git a/PltApp.cpp b/PltApp.cpp index eef1497..72719a8 100644 --- a/PltApp.cpp +++ b/PltApp.cpp @@ -835,15 +835,11 @@ void PltApp::PltAppInit(bool bSubVolume) { cursor = XCreateFontCursor(display, XC_left_ptr); // No need to store these widgets in the class after this function is called. - Widget wPalFrame, wPlotFrame, wPalForm; + Widget wMainArea, wPalFrame, wPlotFrame, wPalForm; wMainArea = XtVaCreateManagedWidget("MainArea", xmFormWidgetClass, wAmrVisTopLevel, - XmNkeyboardFocusPolicy, XmPOINTER, NULL); - - // Add global ESC key handler to main area which can receive keyboard focus - AddStaticEventHandler(wMainArea, KeyPressMask, &PltApp::DoGlobalKeyPress); // ------------------------------- menu bar Widget wMenuBar, wMenuPulldown, wid, wCascade; @@ -2367,39 +2363,7 @@ void PltApp::DoSubregion(Widget, XtPointer, XtPointer) { #endif } // end DoSubregion - -// ------------------------------------------------------------------- -void PltApp::ClearSelection() { - // Clear the selection by setting the selectionBox to an empty state - selectionBox.setSmall(Amrvis::XDIR, 0); - selectionBox.setBig(Amrvis::XDIR, 0); -#if (BL_SPACEDIM != 1) - selectionBox.setSmall(Amrvis::YDIR, 0); - selectionBox.setBig(Amrvis::YDIR, 0); -#endif -#if (BL_SPACEDIM == 3) - selectionBox.setSmall(Amrvis::ZDIR, 0); - selectionBox.setBig(Amrvis::ZDIR, 0); - // Clear the 3D cutting coordinates - for(int np = 0; np < Amrvis::NPLANES; ++np) { - startcutX[np] = 0; - startcutY[np] = 0; - finishcutX[np] = 0; - finishcutY[np] = 0; - // Clear subcut by setting all coordinates to 0 (invalid region) - amrPicturePtrArray[np]->SetSubCut(0, 0, 0, 0); - } -#endif - - // Clear the 2D selection region for all planes by setting invalid coordinates - for(int np = 0; np < Amrvis::NPLANES; ++np) { - amrPicturePtrArray[np]->SetRegion(0, 0, 0, 0); - amrPicturePtrArray[np]->DoExposePicture(); - } -} - - // ------------------------------------------------------------------- void PltApp::DoDatasetButton(Widget, XtPointer, XtPointer) { #if (BL_SPACEDIM == 1) @@ -4131,17 +4095,6 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) case NoExpose: break; - case KeyPress: { - KeySym keysym = XLookupKeysym(&nextEvent.xkey, 0); - if(keysym == XK_Escape) { - // ESC key pressed - clear selection and exit rubber banding - avxGrab.ExplicitUngrab(); - ClearSelection(); - return; - } - } - break; - default: break; } // end switch @@ -4488,17 +4441,6 @@ void PltApp::DoRubberBanding(Widget, XtPointer client_data, XtPointer call_data) } // end DoRubberBanding -// ------------------------------------------------------------------- -void PltApp::DoGlobalKeyPress(Widget, XtPointer, XtPointer call_data) { - XKeyPressedEvent *event = (XKeyPressedEvent *) call_data; - KeySym keysym = XLookupKeysym(event, 0); - if(keysym == XK_Escape) { - // ESC key pressed - clear any existing selection - ClearSelection(); - } -} - - // ------------------------------------------------------------------- void PltApp::DoExposePalette(Widget, XtPointer, XtPointer) { pltPaletteptr->ExposePalette(); From 6ff38edf5ec0518b7becca124fbd4edff1692421 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Sat, 14 Jun 2025 14:42:33 -0400 Subject: [PATCH 8/9] update docs to mention XYPlotWin --- Docs/Amrvis.tex | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/Docs/Amrvis.tex b/Docs/Amrvis.tex index e610fd8..aafc809 100644 --- a/Docs/Amrvis.tex +++ b/Docs/Amrvis.tex @@ -197,6 +197,13 @@ \subsubsection{Interface Windows and Regions} drawn around the corresponding data point in the Data Image Area (the color data image). +\item[XY Plot Window] This window displays 1D line plots of data values +and is created when using the middle or right mouse buttons to draw +lines across the data view. The plot shows the variation of the selected +quantity along the line. Multiple line plots can be overlaid in the same +window for comparison. The window includes controls for animation through +time steps, displaying the plots from multiple files at the same position. + \item[Animation Control Area] This area contains controls for animating through data files and through planes in 3D. It is in the lower right part of the Data View Window below the Palette Area. It also shows @@ -316,11 +323,15 @@ \subsubsection{Mouse Controls} in the isometric view, translating the image in the isometric view (with the shift button pressed), and clicking a point for its data value. -\item [Middle Button] Placing horizontal planar cutting lines in the -orthogonal image views and rotating around the eye point in the isometric view. +\item [Middle Button] Creating horizontal 1D line plots by clicking and dragging to draw +a horizontal line across the data view. When the button is released, a separate XY plot +window opens showing the data values along that line (X-direction plot at the selected +Y position). In 3D, this also rotates around the eye point in the isometric view. -\item [Right Button] Placing vertical planar cutting lines in the -orthogonal image views and zooming the isometric view (pull or push the mouse). +\item [Right Button] Creating vertical 1D line plots by clicking and dragging to draw +a vertical line across the data view. When the button is released, a separate XY plot +window opens showing the data values along that line (Y-direction plot at the selected +X position). In 3D, this also zooms the isometric view (pull or push the mouse). \end{description} From a463c00860dcc74785b581cbaa7ac90b78072e02 Mon Sep 17 00:00:00 2001 From: Ben Wibking Date: Sat, 14 Jun 2025 16:20:52 -0400 Subject: [PATCH 9/9] update docs to note that shift-click is required for 1D line plots --- Docs/Amrvis.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Docs/Amrvis.tex b/Docs/Amrvis.tex index aafc809..54ffd34 100644 --- a/Docs/Amrvis.tex +++ b/Docs/Amrvis.tex @@ -198,8 +198,8 @@ \subsubsection{Interface Windows and Regions} (the color data image). \item[XY Plot Window] This window displays 1D line plots of data values -and is created when using the middle or right mouse buttons to draw -lines across the data view. The plot shows the variation of the selected +and is created when holding shift while using the middle or right mouse buttons +to draw lines across the data view. The plot shows the variation of the selected quantity along the line. Multiple line plots can be overlaid in the same window for comparison. The window includes controls for animation through time steps, displaying the plots from multiple files at the same position. @@ -323,15 +323,15 @@ \subsubsection{Mouse Controls} in the isometric view, translating the image in the isometric view (with the shift button pressed), and clicking a point for its data value. -\item [Middle Button] Creating horizontal 1D line plots by clicking and dragging to draw -a horizontal line across the data view. When the button is released, a separate XY plot -window opens showing the data values along that line (X-direction plot at the selected -Y position). In 3D, this also rotates around the eye point in the isometric view. +\item [Middle Button] Creating horizontal 1D line plots by holding shift while clicking +and dragging to draw a horizontal line across the data view. When the button is released, +a separate XY plot window opens showing the data values along that line (X-direction plot +at the selected Y position). In 3D, this also rotates around the eye point in the isometric view. -\item [Right Button] Creating vertical 1D line plots by clicking and dragging to draw -a vertical line across the data view. When the button is released, a separate XY plot -window opens showing the data values along that line (Y-direction plot at the selected -X position). In 3D, this also zooms the isometric view (pull or push the mouse). +\item [Right Button] Creating vertical 1D line plots by holding shift while clicking +and dragging to draw a vertical line across the data view. When the button is released, +a separate XY plot window opens showing the data values along that line (Y-direction plot +at the selected X position). In 3D, this also zooms the isometric view (pull or push the mouse). \end{description}