Skip to content

Commit 7441b09

Browse files
soswowscott-wilson
authored andcommitted
fix(iv): do not resize on open and other zoom fixes (AcademySoftwareFoundation#4766)
Fixes AcademySoftwareFoundation#4718 See the demo of problems that were fixed and of fixes in action over here: https://www.loom.com/share/3bdee20b32434e0bbba47d393928d4f7 There are fixed for three problems: 1) Window is not resizing when new image is loaded in (it still does when image being loaded is the only one) 2) When you using scroll mouse wheel it is taking into account where the cursor is (there is some corner case when it doesn't do it perfectly, that I can't catch when it doesn't follow it exactly, but a bit of panning fixes it) ~~3) Switching between images recenters (if image is smaller) or making some other panning nessery to have image in the viewport. I believe it is doing same stuff what happens when window is resized.~~ This has been reverted. --------- Signed-off-by: Aleksandr Motsjonov <[email protected]> Signed-off-by: Scott Wilson <[email protected]>
1 parent 8bf54be commit 7441b09

File tree

5 files changed

+50
-57
lines changed

5 files changed

+50
-57
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ gastest.o
2323
/*.exr
2424
/*.tif
2525
/*.jpg
26+
/*.png
2627
/*.jxl
2728
/*.tx
2829
/*.log

src/iv/imageviewer.cpp

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -854,14 +854,11 @@ ImageViewer::open()
854854
if (filename.empty())
855855
continue;
856856
add_image(filename);
857-
// int n = m_images.size()-1;
858-
// IvImage *newimage = m_images[n];
859-
// newimage->read_iv (0, false, image_progress_callback, this);
860857
}
858+
861859
if (old_lastimage >= 0) {
862860
// Otherwise, add_image already did this for us.
863861
current_image(old_lastimage + 1);
864-
fitWindowToImage(true, true);
865862
}
866863
}
867864

@@ -887,7 +884,6 @@ ImageViewer::openRecentFile()
887884
if (m_images.size() > 1) {
888885
// Otherwise, add_image already did this for us.
889886
current_image(m_images.size() - 1);
890-
fitWindowToImage(true, true);
891887
}
892888
}
893889
}
@@ -2009,67 +2005,59 @@ ImageViewer::print()
20092005
}
20102006

20112007

2012-
20132008
void
2014-
ImageViewer::zoomIn()
2009+
ImageViewer::zoomIn(bool smooth)
20152010
{
20162011
IvImage* img = cur();
20172012
if (!img)
20182013
return;
2019-
if (zoom() >= 64)
2014+
2015+
float current_zoom = zoom();
2016+
if (current_zoom >= 64)
20202017
return;
2021-
float oldzoom = zoom();
2022-
float newzoom = ceil2f(oldzoom);
20232018

2024-
float xc, yc; // Center view position
2025-
glwin->get_center(xc, yc);
2026-
int xm, ym; // Mouse position
2027-
glwin->get_focus_image_pixel(xm, ym);
2028-
float xoffset = xc - xm;
2029-
float yoffset = yc - ym;
2030-
float maxzoomratio = std::max(oldzoom / newzoom, newzoom / oldzoom);
2031-
int nsteps = (int)OIIO::clamp(20 * (maxzoomratio - 1), 2.0f, 10.0f);
2032-
for (int i = 1; i <= nsteps; ++i) {
2033-
float a = (float)i / (float)nsteps; // Interpolation amount
2034-
float z = OIIO::lerp(oldzoom, newzoom, a);
2035-
float zoomratio = z / oldzoom;
2036-
view(xm + xoffset / zoomratio, ym + yoffset / zoomratio, z, false);
2037-
if (i != nsteps) {
2038-
QApplication::processEvents();
2039-
Sysutil::usleep(1000000 / 4 / nsteps);
2040-
}
2041-
}
2019+
float newzoom = ceil2f(current_zoom);
20422020

2043-
fitImageToWindowAct->setChecked(false);
2021+
this->zoomToCursor(newzoom, smooth);
20442022
}
20452023

20462024

2047-
20482025
void
2049-
ImageViewer::zoomOut()
2026+
ImageViewer::zoomOut(bool smooth)
20502027
{
20512028
IvImage* img = cur();
20522029
if (!img)
20532030
return;
2054-
if (zoom() <= 1.0f / 64)
2031+
2032+
float current_zoom = zoom();
2033+
if (current_zoom <= 1.0f / 64)
20552034
return;
2035+
2036+
float newzoom = floor2f(current_zoom);
2037+
2038+
this->zoomToCursor(newzoom, smooth);
2039+
}
2040+
2041+
2042+
void
2043+
ImageViewer::zoomToCursor(float newzoom, bool smooth)
2044+
{
20562045
float oldzoom = zoom();
2057-
float newzoom = floor2f(oldzoom);
2058-
2059-
float xcpel, ycpel; // Center view position
2060-
glwin->get_center(xcpel, ycpel);
2061-
int xmpel, ympel; // Mouse position
2062-
glwin->get_focus_image_pixel(xmpel, ympel);
2063-
float xoffset = xcpel - xmpel;
2064-
float yoffset = ycpel - ympel;
2046+
float xc, yc; // Center view position
2047+
glwin->get_center(xc, yc);
2048+
int xm, ym; // Mouse position
2049+
glwin->get_focus_image_pixel(xm, ym);
2050+
float xoffset = xc - xm;
2051+
float yoffset = yc - ym;
2052+
20652053
float maxzoomratio = std::max(oldzoom / newzoom, newzoom / oldzoom);
2066-
int nsteps = (int)OIIO::clamp(20 * (maxzoomratio - 1), 2.0f, 10.0f);
2054+
int nsteps = smooth ? (int)OIIO::clamp(20 * (maxzoomratio - 1), 2.0f, 10.0f)
2055+
: 1;
20672056
for (int i = 1; i <= nsteps; ++i) {
20682057
float a = (float)i / (float)nsteps; // Interpolation amount
20692058
float z = OIIO::lerp(oldzoom, newzoom, a);
20702059
float zoomratio = z / oldzoom;
2071-
view(xmpel + xoffset / zoomratio, ympel + yoffset / zoomratio, z,
2072-
false);
2060+
view(xm + xoffset / zoomratio, ym + yoffset / zoomratio, z, false);
20732061
if (i != nsteps) {
20742062
QApplication::processEvents();
20752063
Sysutil::usleep(1000000 / 4 / nsteps);

src/iv/imageviewer.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,10 +265,12 @@ private slots:
265265
void moveToNewWindow(); ///< Split current image off as a new window
266266
void print(); ///< Print current image
267267
void deleteCurrentImage(); ///< Deleting displayed image
268-
void zoomIn(); ///< Zoom in to next power of 2
269-
void zoomOut(); ///< Zoom out to next power of 2
270-
void normalSize(); ///< Adjust zoom to 1:1
271-
void fitImageToWindow(); ///< Adjust zoom to fit window exactly
268+
void zoomIn(bool smooth = true); ///< Zoom in to next power of 2
269+
void zoomOut(bool smooth = true); ///< Zoom out to next power of 2
270+
void zoomToCursor(float newzoom,
271+
bool smooth = true); ///< Zoom to a specific level
272+
void normalSize(); ///< Adjust zoom to 1:1
273+
void fitImageToWindow(); ///< Adjust zoom to fit window exactly
272274
/// Resize window to fit image exactly. If zoomok is false, do not
273275
/// change the zoom, even to fit on screen. If minsize is true, do not
274276
/// resize smaller than default_width x default_height.

src/iv/ivgl.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,13 +1218,13 @@ IvGL::mousePressEvent(QMouseEvent* event)
12181218
switch (event->button()) {
12191219
case Qt::LeftButton:
12201220
if (mousemode == ImageViewer::MouseModeZoom && !Alt)
1221-
m_viewer.zoomIn();
1221+
m_viewer.zoomIn(true); // Animated zoom for mouse clicks
12221222
else
12231223
m_dragging = true;
12241224
return;
12251225
case Qt::RightButton:
12261226
if (mousemode == ImageViewer::MouseModeZoom && !Alt)
1227-
m_viewer.zoomOut();
1227+
m_viewer.zoomOut(true); // Animated zoom for mouse clicks
12281228
else
12291229
m_dragging = true;
12301230
return;
@@ -1328,9 +1328,11 @@ IvGL::wheelEvent(QWheelEvent* event)
13281328
QPoint angdelta = event->angleDelta() / 8; // div by 8 to get degrees
13291329
if (abs(angdelta.y()) > abs(angdelta.x()) // predominantly vertical
13301330
&& abs(angdelta.y()) > 2) { // suppress tiny motions
1331-
float oldzoom = m_viewer.zoom();
1332-
float newzoom = (angdelta.y() > 0) ? ceil2f(oldzoom) : floor2f(oldzoom);
1333-
m_viewer.zoom(newzoom);
1331+
if (angdelta.y() > 0) {
1332+
m_viewer.zoomIn(false);
1333+
} else {
1334+
m_viewer.zoomOut(false);
1335+
}
13341336
event->accept();
13351337
}
13361338
// TODO: Update this to keep the zoom centered on the event .x, .y

src/libtexture/imagecache_pvt.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ class OIIO_API ImageCacheFile final : public RefCnt {
266266
/// precompute.
267267
struct LevelInfo {
268268
std::unique_ptr<ImageSpec> m_spec; ///< ImageSpec for the mip level,
269-
// only specified if different from nativespec
269+
// only specified if different from nativespec
270270
ImageSpec nativespec; ///< Native ImageSpec for the mip level
271271
mutable std::unique_ptr<float[]> polecolor; ///< Pole colors
272272
atomic_ll* tiles_read; ///< Bitfield for tiles read at least once
@@ -394,10 +394,10 @@ class OIIO_API ImageCacheFile final : public RefCnt {
394394
std::atomic<std::shared_ptr<ImageInput>> m_input;
395395
#else
396396
std::shared_ptr<ImageInput> m_input; ///< Open ImageInput, NULL if closed
397-
// Note that m_input, the shared pointer itself, is NOT safe to
398-
// access directly. ALWAYS retrieve its value with get_imageinput
399-
// (it's thread-safe to use that result) and set its value with
400-
// set_imageinput -- those are guaranteed thread-safe.
397+
// Note that m_input, the shared pointer itself, is NOT safe to
398+
// access directly. ALWAYS retrieve its value with get_imageinput
399+
// (it's thread-safe to use that result) and set its value with
400+
// set_imageinput -- those are guaranteed thread-safe.
401401
#endif
402402
std::vector<SubimageInfo> m_subimages; ///< Info on each subimage
403403
TexFormat m_texformat; ///< Which texture format

0 commit comments

Comments
 (0)