From 58995a052db23009db3c8341a0f189163d0f3f7a Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Apr 2021 15:44:49 -0700 Subject: [PATCH 01/18] Properly enable inspector window for film strip --- rtgui/filebrowserentry.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 432296f38..5e8c730aa 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -294,7 +294,7 @@ bool FileBrowserEntry::motionNotify (int x, int y) Inspector* inspector = parent->getInspector(); - if (inspector && inspector->isActive() && !parent->isInTabMode()) { + if (inspector && inspector->isActive() && (!parent->isInTabMode() || options.inspectorWindow)) { const rtengine::Coord2D coord(getPosInImgSpace(x, y)); if (coord.x != -1.) { From 61aba8ad08f17f7fe3091725ca8c790518266c61 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Apr 2021 15:48:29 -0700 Subject: [PATCH 02/18] Set inspector window title from language files --- rtdata/languages/default | 1 + rtgui/inspector.cc | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 595f03e7e..abc5f1609 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1462,6 +1462,7 @@ ICCPROFCREATOR_PROF_V4;ICC v4 ICCPROFCREATOR_SAVEDIALOG_TITLE;Save ICC profile as... ICCPROFCREATOR_SLOPE;Slope ICCPROFCREATOR_TRC_PRESET;Tone response curve +INSPECTOR_WINDOW_TITLE;Inspector IPTCPANEL_CATEGORY;Category IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider. IPTCPANEL_CITY;City diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 37ed20207..711a96615 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -21,6 +21,7 @@ #include #include "cursormanager.h" #include "guiutils.h" +#include "multilangmgr.h" #include "options.h" #include "pathutils.h" #include "rtscalable.h" @@ -91,7 +92,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca } else { window = new Gtk::Window(); - window->set_title("RawTherapee Inspector"); + window->set_title("RawTherapee " + M("INSPECTOR_WINDOW_TITLE")); window->set_visible(false); window->add_events(Gdk::KEY_PRESS_MASK); window->signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); From 67e18b5c53fc24de2fec155d59623937f80328e1 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Apr 2021 17:05:02 -0700 Subject: [PATCH 03/18] Fix inspector window sometimes not hiding When the f shortcut is quickly pressed, the inspector window will sometimes open and remain open even though it should automatically close. This commit ensures the window closes by capturing the f key release event from the main window in addition to the inspector window. --- rtgui/filecatalog.cc | 15 +++++++++++++++ rtgui/filecatalog.h | 1 + rtgui/filepanel.cc | 9 +++++++++ rtgui/filepanel.h | 1 + rtgui/inspector.cc | 5 +++++ rtgui/inspector.h | 5 +++++ rtgui/rtwindow.cc | 9 +++++++++ rtgui/rtwindow.h | 1 + 8 files changed, 46 insertions(+) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index dbea4ade9..cdcb00195 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -2524,6 +2524,21 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) return fileBrowser->keyPressed(event); } +bool FileCatalog::handleShortcutKeyRelease(GdkEventKey* event) +{ + bool ctrl = event->state & GDK_CONTROL_MASK; + bool alt = event->state & GDK_MOD1_MASK; + + if (!ctrl && !alt) { + switch (event->keyval) { + case GDK_KEY_f: + case GDK_KEY_F: + fileBrowser->getInspector()->hideWindow(); + return true; + } + } +} + void FileCatalog::showToolBar() { if (hbToolBar1STB) { diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h index c7c4f3155..23d56af73 100644 --- a/rtgui/filecatalog.h +++ b/rtgui/filecatalog.h @@ -276,6 +276,7 @@ public: void openNextPreviousEditorImage (Glib::ustring fname, bool clearFilters, eRTNav nextPrevious); bool handleShortcutKey (GdkEventKey* event); + bool handleShortcutKeyRelease(GdkEventKey *event); bool CheckSidePanelsVisibility(); void toggleSidePanels(); diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index a09a82597..974482f41 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -412,6 +412,15 @@ bool FilePanel::handleShortcutKey (GdkEventKey* event) return false; } +bool FilePanel::handleShortcutKeyRelease(GdkEventKey *event) +{ + if(fileCatalog->handleShortcutKeyRelease(event)) { + return true; + } + + return false; +} + void FilePanel::loadingThumbs(Glib::ustring str, double rate) { GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h index 65e1ea548..ba5dfa7c9 100644 --- a/rtgui/filepanel.h +++ b/rtgui/filepanel.h @@ -81,6 +81,7 @@ public: bool imageLoaded( Thumbnail* thm, ProgressConnector * ); bool handleShortcutKey (GdkEventKey* event); + bool handleShortcutKeyRelease(GdkEventKey *event); void updateTPVScrollbar (bool hide); private: diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 711a96615..7ca0b92d0 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -144,6 +144,11 @@ void Inspector::showWindow(bool scaled, bool fullscreen) mouseMove(next_image_pos, 0); } +void Inspector::hideWindow() +{ + window->set_visible(false); +} + bool Inspector::on_key_release(GdkEventKey *event) { if (!window) diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 726bc947c..52c95d14c 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -91,6 +91,11 @@ public: */ void showWindow(bool scaled, bool fullscreen = true); + /** + * Hide the window. + */ + void hideWindow(); + /** @brief Mouse movement to a new position * @param pos Location of the mouse, in percentage (i.e. [0;1] range) relative to the full size image ; -1,-1 == out of the image * @param transform H/V flip and coarse rotation transformation diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index c0042f949..cf77374ce 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -285,6 +285,7 @@ RTWindow::RTWindow () property_destroy_with_parent().set_value (false); signal_window_state_event().connect ( sigc::mem_fun (*this, &RTWindow::on_window_state_event) ); signal_key_press_event().connect ( sigc::mem_fun (*this, &RTWindow::keyPressed) ); + signal_key_release_event().connect(sigc::mem_fun(*this, &RTWindow::keyReleased)); if (simpleEditor) { epanel = Gtk::manage ( new EditorPanel (nullptr) ); @@ -756,6 +757,14 @@ bool RTWindow::keyPressed (GdkEventKey* event) return false; } +bool RTWindow::keyReleased(GdkEventKey *event) +{ + if (mainNB->get_current_page() == mainNB->page_num(*fpanel)) { + return fpanel->handleShortcutKeyRelease(event); + } + return false; +} + void RTWindow::addBatchQueueJob (BatchQueueEntry* bqe, bool head) { diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index e5e180747..aa1830d89 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -85,6 +85,7 @@ public: void addBatchQueueJobs (const std::vector& entries); bool keyPressed (GdkEventKey* event); + bool keyReleased(GdkEventKey *event); bool on_configure_event (GdkEventConfigure* event) override; bool on_delete_event (GdkEventAny* event) override; bool on_window_state_event (GdkEventWindowState* event) override; From d4bceb5c06b256debf76051a5e2da4108bc253ca Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Apr 2021 17:27:57 -0700 Subject: [PATCH 04/18] Pin inspector window if opened with context menu --- rtgui/filebrowser.cc | 2 +- rtgui/inspector.cc | 4 ++-- rtgui/inspector.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 0d2451b59..0246520ee 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -2100,5 +2100,5 @@ void FileBrowser::openRequested( std::vector mselected) void FileBrowser::inspectRequested(std::vector mselected) { - getInspector()->showWindow(false, false); + getInspector()->showWindow(false, false, true); } diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 7ca0b92d0..242ebac24 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -117,7 +117,7 @@ Inspector::~Inspector() delete window; } -void Inspector::showWindow(bool scaled, bool fullscreen) +void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) { if (!window) return; @@ -137,7 +137,7 @@ void Inspector::showWindow(bool scaled, bool fullscreen) window->unfullscreen(); this->fullscreen = fullscreen; window->set_visible(true); - pinned = false; + this->pinned = pinned; // update content when becoming visible switchImage(next_image_path); diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 52c95d14c..62bcef471 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -89,7 +89,7 @@ public: /** @brief Show or hide window * @param scaled fit image into window */ - void showWindow(bool scaled, bool fullscreen = true); + void showWindow(bool scaled, bool fullscreen = true, bool pinned = false); /** * Hide the window. From 900af7aeb7c9e9ba71c0a2e4d489f7b853790cd3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 25 Apr 2021 18:11:47 -0700 Subject: [PATCH 05/18] Remove drawn background in inspector window Add "InspectorWindow" CSS ID so that the background color can be changed through CSS. --- rtgui/inspector.cc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 242ebac24..c43e3863e 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -92,6 +92,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca } else { window = new Gtk::Window(); + window->set_name("InspectorWindow"); window->set_title("RawTherapee " + M("INSPECTOR_WINDOW_TITLE")); window->set_visible(false); window->add_events(Gdk::KEY_PRESS_MASK); @@ -450,15 +451,6 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) // draw the background style->render_background(cr, 0, 0, get_width(), get_height()); } - else { - ///* --- old method (the new method does not seem to work) - c = style->get_background_color (Gtk::STATE_FLAG_NORMAL); - cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); - cr->set_line_width (0); - cr->rectangle (0, 0, availableSize.x, availableSize.y); - cr->fill (); - //*/ - } bool scaledImage = scale != 1.0; if (!window || (deviceScale == 1 && !scaledImage)) { From 5decec540542a9769f410a6ab50265a59a771b81 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 1 May 2021 15:48:50 -0700 Subject: [PATCH 06/18] Fix inspector window zoom centering Use floating point coordinates instead of integers to avoid rounding errors. --- rtgui/inspector.cc | 59 +++++++++++++++++++++++++++++----------------- rtgui/inspector.h | 5 ++-- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index c43e3863e..d212787df 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -333,8 +333,17 @@ void Inspector::beginZoom(double x, double y) moveCenter(0, 0, imW, imH, deviceScale); // store center and current position for zooming - dcenterBegin.x = (x - window->get_width()/2) / scale * deviceScale; - dcenterBegin.y = (y - window->get_height()/2) / scale * deviceScale; + double cur_scale = zoomScale; + if (scaled) { + Glib::RefPtr win = get_window(); + double winW = win->get_width() * deviceScale; + double winH = win->get_height() * deviceScale; + int imW = rtengine::max(currImage->imgBuffer.getWidth(), 1); + int imH = rtengine::max(currImage->imgBuffer.getHeight(), 1); + cur_scale *= rtengine::min(winW / imW, winH / imH); + } + dcenterBegin.x = (x - window->get_width() / 2.) / cur_scale * deviceScale; + dcenterBegin.y = (y - window->get_height() / 2.) / cur_scale * deviceScale; centerBegin = center; zoomScaleBegin = zoomScale; @@ -385,15 +394,16 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) // this will eventually create/update the off-screen pixmap // compute the displayed area - rtengine::Coord availableSize; - rtengine::Coord topLeft; - rtengine::Coord dest(0, 0); + rtengine::Coord2D availableSize; + rtengine::Coord2D topLeft; + rtengine::Coord topLeftInt; + rtengine::Coord2D dest(0, 0); int deviceScale = window? get_scale_factor(): 1; availableSize.x = win->get_width() * deviceScale; availableSize.y = win->get_height() * deviceScale; int imW = rtengine::max(currImage->imgBuffer.getWidth(), 1); int imH = rtengine::max(currImage->imgBuffer.getHeight(), 1); - scale = rtengine::min((double)availableSize.x / imW, (double)availableSize.y / imH); + scale = rtengine::min(availableSize.x / imW, availableSize.y / imH); if (scaled) { // reduce size of image to fit into window, no further zoom down zoomScale = rtengine::max(zoomScale, 1.0); @@ -410,33 +420,36 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) if (imW < availableSize.x) { // center the image in the available space along X topLeft.x = 0; - dest.x = (availableSize.x - imW) / 2; + dest.x = (availableSize.x - imW) / 2.; } else { // partial image display // double clamp - topLeft.x = center.x + availableSize.x / 2; - topLeft.x = rtengine::min(topLeft.x, imW); + topLeft.x = center.x + availableSize.x / 2.; + topLeft.x = rtengine::min(topLeft.x, imW); topLeft.x -= availableSize.x; - topLeft.x = rtengine::max(topLeft.x, 0); + topLeft.x = rtengine::max(topLeft.x, 0); } if (imH < availableSize.y) { // center the image in the available space along Y topLeft.y = 0; - dest.y = (availableSize.y - imH) / 2; + dest.y = (availableSize.y - imH) / 2.; } else { // partial image display // double clamp - topLeft.y = center.y + availableSize.y / 2; - topLeft.y = rtengine::min(topLeft.y, imH); + topLeft.y = center.y + availableSize.y / 2.; + topLeft.y = rtengine::min(topLeft.y, imH); topLeft.y -= availableSize.y; - topLeft.y = rtengine::max(topLeft.y, 0); + topLeft.y = rtengine::max(topLeft.y, 0); } //printf("center: %d, %d (img: %d, %d) (availableSize: %d, %d) (topLeft: %d, %d)\n", center.x, center.y, imW, imH, availableSize.x, availableSize.y, topLeft.x, topLeft.y); + topLeftInt.x = floor(topLeft.x); + topLeftInt.y = floor(topLeft.y); + // define the destination area - currImage->imgBuffer.setDrawRectangle(win, dest.x, dest.y, rtengine::min(availableSize.x - dest.x, imW), rtengine::min(availableSize.y - dest.y, imH), false); - currImage->imgBuffer.setSrcOffset(topLeft.x, topLeft.y); + currImage->imgBuffer.setDrawRectangle(win, dest.x, dest.y, rtengine::min(ceil(availableSize.x + (topLeft.x - topLeftInt.x) - 2 * dest.x), imW), rtengine::min(ceil(availableSize.y + (topLeft.y - topLeftInt.y) - 2 * dest.y), imH), false); + currImage->imgBuffer.setSrcOffset(topLeftInt.x, topLeftInt.y); if (!currImage->imgBuffer.surfaceCreated()) { return false; @@ -464,16 +477,18 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) cairo_surface_set_device_scale(cr->get_target()->cobj(), scale, scale); scaledImage = false; } - int viewW = rtengine::min(imW, availableSize.x); - int viewH = rtengine::min(imH, availableSize.y); - Glib::RefPtr crop = Gdk::Pixbuf::create(currImage->imgBuffer.getSurface(), topLeft.x, topLeft.y, viewW, viewH); + int viewW = rtengine::min(imW, ceil(availableSize.x + (topLeft.x - topLeftInt.x))); + int viewH = rtengine::min(imH, ceil(availableSize.y + (topLeft.y - topLeftInt.y))); + Glib::RefPtr crop = Gdk::Pixbuf::create(currImage->imgBuffer.getSurface(), topLeftInt.x, topLeftInt.y, viewW, viewH); if (!scaledImage) { Gdk::Cairo::set_source_pixbuf(cr, crop, dest.x, dest.y); } else { + double dx = scale * (dest.x + topLeftInt.x - topLeft.x); + double dy = scale * (dest.y + topLeftInt.y - topLeft.y); // scale crop as the device does not seem to support it (Linux) - crop = crop->scale_simple(viewW*scale, viewH*scale, Gdk::INTERP_BILINEAR); - Gdk::Cairo::set_source_pixbuf(cr, crop, dest.x*scale, dest.y*scale); + crop = crop->scale_simple(round(viewW*scale), round(viewH*scale), Gdk::INTERP_BILINEAR); + Gdk::Cairo::set_source_pixbuf(cr, crop, dx, dy); } cr->paint(); } @@ -504,7 +519,7 @@ void Inspector::mouseMove (rtengine::Coord2D pos, int transform) return; if (currImage) { - center.set(int(rtengine::LIM01(pos.x)*double(currImage->imgBuffer.getWidth())), int(rtengine::LIM01(pos.y)*double(currImage->imgBuffer.getHeight()))); + center.set(rtengine::LIM01(pos.x)*double(currImage->imgBuffer.getWidth()), rtengine::LIM01(pos.y)*double(currImage->imgBuffer.getHeight())); } else { center.set(0, 0); } diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 62bcef471..b17d199bf 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -22,7 +22,6 @@ #include "guiutils.h" -#include "../rtengine/coord.h" #include "../rtengine/coord2d.h" class InspectorBuffer @@ -44,13 +43,13 @@ class Inspector final : public Gtk::DrawingArea { private: - rtengine::Coord center; + rtengine::Coord2D center; std::vector images; InspectorBuffer* currImage; bool scaled; // fit image into window double scale; // current scale double zoomScale, zoomScaleBegin; // scale during zoom - rtengine::Coord centerBegin, dcenterBegin; // center during zoom + rtengine::Coord2D centerBegin, dcenterBegin; // center during zoom bool active; bool pinned; bool dirty; From e25cb3fde0665f1060e9fa6d8dba2414671002d3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 1 May 2021 15:52:45 -0700 Subject: [PATCH 07/18] Fix inspector window panning speed Consistently use integers for mouse movement and compensate for image scale. --- rtgui/inspector.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index d212787df..59378b9d2 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -227,13 +227,15 @@ bool Inspector::on_motion_notify_event(GdkEventMotion *event) return false; int deviceScale = get_scale_factor(); - int delta_x = (button_pos.x - event->x)*deviceScale; - int delta_y = (button_pos.y - event->y)*deviceScale; + int event_x = round(event->x); + int event_y = round(event->y); + int delta_x = (button_pos.x - event_x) * deviceScale; + int delta_y = (button_pos.y - event_y) * deviceScale; int imW = currImage->imgBuffer.getWidth(); int imH = currImage->imgBuffer.getHeight(); moveCenter(delta_x, delta_y, imW, imH, deviceScale); - button_pos.set(event->x, event->y); + button_pos.set(event_x, event_y); if (!dirty) { dirty = true; @@ -316,8 +318,8 @@ void Inspector::moveCenter(int delta_x, int delta_y, int imW, int imH, int devic rtengine::Coord margin; // limit to image size margin.x = rtengine::min(window->get_width() * deviceScale / scale, imW) / 2; margin.y = rtengine::min(window->get_height() * deviceScale / scale, imH) / 2; - center.set(rtengine::LIM(center.x + delta_x, margin.x, imW - margin.x), - rtengine::LIM(center.y + delta_y, margin.y, imH - margin.y)); + center.set(rtengine::LIM(center.x + delta_x / scale, margin.x, imW - margin.x), + rtengine::LIM(center.y + delta_y / scale, margin.y, imH - margin.y)); } void Inspector::beginZoom(double x, double y) From b99b9302cce5a8e175fc7faf87edc6c745f22fd3 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 May 2021 12:31:33 -0700 Subject: [PATCH 08/18] Fix inspector window scaling with caps lock When launched with the accelerator key, the inspector window initially scales the image without respecting the state of the caps lock. This commit fixes the bug. --- rtgui/filecatalog.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index cdcb00195..d0316a2d4 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -2515,8 +2515,10 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) if (!ctrl && !alt) { switch (event->keyval) { case GDK_KEY_f: + fileBrowser->getInspector()->showWindow(true); + return true; case GDK_KEY_F: - fileBrowser->getInspector()->showWindow(!shift); + fileBrowser->getInspector()->showWindow(false); return true; } } From 4811f92c399a5941175591c578f30baffe9cb8ec Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 May 2021 12:35:05 -0700 Subject: [PATCH 09/18] Add missing return statement --- rtgui/filecatalog.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index d0316a2d4..a685bebe9 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -2539,6 +2539,8 @@ bool FileCatalog::handleShortcutKeyRelease(GdkEventKey* event) return true; } } + + return false; } void FileCatalog::showToolBar() From de9403f9fe27c9d36cb48cbac4663952301e581c Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 May 2021 12:52:15 -0700 Subject: [PATCH 10/18] Ignore key down repeat events in inspector window Ignore key press events that happen when a key is held down. --- rtgui/inspector.cc | 12 +++++++++++- rtgui/inspector.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 59378b9d2..e0da8378e 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -83,7 +83,7 @@ InspectorBuffer::~InspectorBuffer() { // return deg; //} -Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false) +Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false), keyDown(false) { set_name("Inspector"); @@ -152,6 +152,8 @@ void Inspector::hideWindow() bool Inspector::on_key_release(GdkEventKey *event) { + keyDown = false; + if (!window) return false; @@ -172,6 +174,12 @@ bool Inspector::on_key_press(GdkEventKey *event) if (!window) return false; + if (keyDown) { + return true; + } + + keyDown = true; + switch (event->keyval) { case GDK_KEY_z: case GDK_KEY_F: @@ -203,6 +211,8 @@ bool Inspector::on_key_press(GdkEventKey *event) return true; } + keyDown = false; + return false; } diff --git a/rtgui/inspector.h b/rtgui/inspector.h index b17d199bf..4d5e5e835 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -55,6 +55,7 @@ private: bool dirty; bool initialized; bool fullscreen; // window is shown in fullscreen mode + bool keyDown; sigc::connection delayconn; Glib::ustring next_image_path; From bce88478c47731eca702d65fc0baaf88d44855ce Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 May 2021 15:50:55 -0700 Subject: [PATCH 11/18] Fix inspector window rendering with device scaling --- rtgui/inspector.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index e0da8378e..c8d9c8bd2 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -485,9 +485,13 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) else { // consider device scale and image scale if (deviceScale > 1) { +#ifdef __APPLE__ // use full device resolution and let it scale the image (macOS) cairo_surface_set_device_scale(cr->get_target()->cobj(), scale, scale); scaledImage = false; +#else + cr->scale(1. / deviceScale, 1. / deviceScale); +#endif } int viewW = rtengine::min(imW, ceil(availableSize.x + (topLeft.x - topLeftInt.x))); int viewH = rtengine::min(imH, ceil(availableSize.y + (topLeft.y - topLeftInt.y))); From 70d30a5050e6784f8b118eb088704df068fc30ea Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 2 May 2021 15:57:34 -0700 Subject: [PATCH 12/18] Fix crash after pressing `f` key in file browser Check that the inspector window exists before trying to close it. --- rtgui/inspector.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index c8d9c8bd2..2de324b29 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -147,6 +147,9 @@ void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) void Inspector::hideWindow() { + if (!window) { + return; + } window->set_visible(false); } From 9495c049c49b73b129ee329546af84db173753c7 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Thu, 6 May 2021 21:39:01 -0700 Subject: [PATCH 13/18] Fix inspector not opening full-screen at first --- rtgui/inspector.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 2de324b29..cf4ae3207 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -126,7 +126,6 @@ void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) // initialize when shown first if (!initialized) { window->show_all(); - window->set_visible(false); initialized = true; } From b2988ddbb32e0bd77805daa4f3e36284cfb91fea Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Fri, 7 May 2021 22:26:28 -0700 Subject: [PATCH 14/18] Avoid reopening inspector window when being opened --- rtgui/inspector.cc | 11 +++++++++-- rtgui/inspector.h | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index cf4ae3207..1534618e4 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -83,7 +83,7 @@ InspectorBuffer::~InspectorBuffer() { // return deg; //} -Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false), keyDown(false) +Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false), keyDown(false), windowShowing(false) { set_name("Inspector"); @@ -98,6 +98,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca window->add_events(Gdk::KEY_PRESS_MASK); window->signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); window->signal_key_press_event().connect(sigc::mem_fun(*this, &Inspector::on_key_press)); + window->signal_hide().connect(sigc::mem_fun(*this, &Inspector::on_window_hide)); add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); gestureZoom = Gtk::GestureZoom::create(*this); @@ -120,7 +121,7 @@ Inspector::~Inspector() void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) { - if (!window) + if (!window || windowShowing) return; // initialize when shown first @@ -138,6 +139,7 @@ void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) this->fullscreen = fullscreen; window->set_visible(true); this->pinned = pinned; + windowShowing = true; // update content when becoming visible switchImage(next_image_path); @@ -218,6 +220,11 @@ bool Inspector::on_key_press(GdkEventKey *event) return false; } +void Inspector::on_window_hide() +{ + windowShowing = false; +} + bool Inspector::on_button_press_event(GdkEventButton *event) { if (!window) diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 4d5e5e835..9ff03f96e 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -56,6 +56,7 @@ private: bool initialized; bool fullscreen; // window is shown in fullscreen mode bool keyDown; + bool windowShowing; sigc::connection delayconn; Glib::ustring next_image_path; @@ -65,6 +66,8 @@ private: bool on_key_release(GdkEventKey *event); bool on_key_press(GdkEventKey *event); + void on_window_hide(); + rtengine::Coord button_pos; bool on_button_press_event(GdkEventButton *event) override; bool on_motion_notify_event(GdkEventMotion *event) override; From 36cb32b31be5702574bcc32e97a82296e465a2be Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 8 May 2021 11:15:41 -0700 Subject: [PATCH 15/18] Make inspector window size consistent --- rtgui/filebrowser.cc | 2 +- rtgui/filecatalog.cc | 4 ++-- rtgui/inspector.cc | 22 +++++++++++++++------- rtgui/inspector.h | 4 +++- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 0246520ee..304e75a5c 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -2100,5 +2100,5 @@ void FileBrowser::openRequested( std::vector mselected) void FileBrowser::inspectRequested(std::vector mselected) { - getInspector()->showWindow(false, false, true); + getInspector()->showWindow(true); } diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index a685bebe9..c45fc154f 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -2515,10 +2515,10 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) if (!ctrl && !alt) { switch (event->keyval) { case GDK_KEY_f: - fileBrowser->getInspector()->showWindow(true); + fileBrowser->getInspector()->showWindow(false, true); return true; case GDK_KEY_F: - fileBrowser->getInspector()->showWindow(false); + fileBrowser->getInspector()->showWindow(false, false); return true; } } diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 1534618e4..9fa1b8773 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -83,7 +83,7 @@ InspectorBuffer::~InspectorBuffer() { // return deg; //} -Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false), keyDown(false), windowShowing(false) +Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomScale(1.0), zoomScaleBegin(1.0), active(false), pinned(false), dirty(false), fullscreen(true), keyDown(false), windowShowing(false) { set_name("Inspector"); @@ -99,6 +99,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca window->signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); window->signal_key_press_event().connect(sigc::mem_fun(*this, &Inspector::on_key_press)); window->signal_hide().connect(sigc::mem_fun(*this, &Inspector::on_window_hide)); + window->signal_window_state_event().connect(sigc::mem_fun(*this, &Inspector::on_inspector_window_state_event)); add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::SMOOTH_SCROLL_MASK); gestureZoom = Gtk::GestureZoom::create(*this); @@ -107,6 +108,7 @@ Inspector::Inspector () : currImage(nullptr), scaled(false), scale(1.0), zoomSca window->add(*this); window->set_size_request(500, 500); + window->fullscreen(); initialized = false; // delay init to avoid flickering on some systems active = true; // always track inspected thumbnails } @@ -119,7 +121,7 @@ Inspector::~Inspector() delete window; } -void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) +void Inspector::showWindow(bool pinned, bool scaled) { if (!window || windowShowing) return; @@ -132,11 +134,6 @@ void Inspector::showWindow(bool scaled, bool fullscreen, bool pinned) // show inspector window this->scaled = scaled; - if (fullscreen) - window->fullscreen(); - else - window->unfullscreen(); - this->fullscreen = fullscreen; window->set_visible(true); this->pinned = pinned; windowShowing = true; @@ -225,6 +222,17 @@ void Inspector::on_window_hide() windowShowing = false; } +bool Inspector::on_inspector_window_state_event(GdkEventWindowState *event) +{ + if (!window->get_window() || window->get_window()->gobj() != event->window) { + return false; + } + + fullscreen = event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; + + return true; +} + bool Inspector::on_button_press_event(GdkEventButton *event) { if (!window) diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 9ff03f96e..5577bfb45 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -67,6 +67,7 @@ private: bool on_key_press(GdkEventKey *event); void on_window_hide(); + bool on_inspector_window_state_event(GdkEventWindowState *event); rtengine::Coord button_pos; bool on_button_press_event(GdkEventButton *event) override; @@ -90,9 +91,10 @@ public: ~Inspector() override; /** @brief Show or hide window + * @param pinned pin window * @param scaled fit image into window */ - void showWindow(bool scaled, bool fullscreen = true, bool pinned = false); + void showWindow(bool pinned, bool scaled = true); /** * Hide the window. From 9df34be6cbf5ed791aa78f3f1761c719208aea09 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sat, 8 May 2021 12:15:58 -0700 Subject: [PATCH 16/18] Hide inspector accelerator in film strip Only show the accelerator key in the context menu when opening the menu from the full file browser but not the film strip. --- rtgui/filebrowser.cc | 15 ++++++++++++++- rtgui/filebrowser.h | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 304e75a5c..37ff6da62 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -411,7 +411,7 @@ FileBrowser::FileBrowser () : untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_Return, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); if (options.inspectorWindow) - inspect->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_F, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + inspect->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_f, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); developfast->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_B, Gdk::CONTROL_MASK | Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); @@ -1374,6 +1374,19 @@ int FileBrowser::getThumbnailHeight () } } +void FileBrowser::enableTabMode(bool enable) +{ + ThumbBrowserBase::enableTabMode(enable); + if (options.inspectorWindow) { + if (enable) { + inspect->remove_accelerator(pmenu->get_accel_group(), GDK_KEY_f, (Gdk::ModifierType)0); + } + else { + inspect->add_accelerator ("activate", pmenu->get_accel_group(), GDK_KEY_f, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + } + } +} + void FileBrowser::applyMenuItemActivated (ProfileStoreLabel *label) { MYREADERLOCK(l, entryRW); diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index 03a8636e5..4602ba9bb 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -182,6 +182,8 @@ public: void saveThumbnailHeight (int height) override; int getThumbnailHeight () override; + + void enableTabMode(bool enable); bool isInTabMode() override { return tbl ? tbl->isInTabMode() : false; From 6535cb4a9454b86164f0017df958b691965ae4d1 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 9 May 2021 12:18:06 -0700 Subject: [PATCH 17/18] Make inspector never upscale in fit-to-window mode When zoomed completely out, don't upscale images. --- rtgui/inspector.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 9fa1b8773..0453564f9 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -432,7 +432,7 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) availableSize.y = win->get_height() * deviceScale; int imW = rtengine::max(currImage->imgBuffer.getWidth(), 1); int imH = rtengine::max(currImage->imgBuffer.getHeight(), 1); - scale = rtengine::min(availableSize.x / imW, availableSize.y / imH); + scale = rtengine::min(1., rtengine::min(availableSize.x / imW, availableSize.y / imH)); if (scaled) { // reduce size of image to fit into window, no further zoom down zoomScale = rtengine::max(zoomScale, 1.0); From 77ea6d92cbfadc1a1c90cee5064dc78501c4d031 Mon Sep 17 00:00:00 2001 From: Lawrence Lee <45837045+Lawrence37@users.noreply.github.com> Date: Sun, 9 May 2021 12:31:26 -0700 Subject: [PATCH 18/18] Pin inspector whenever scrolling or zooming --- rtgui/inspector.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 0453564f9..675da51c6 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -277,6 +277,8 @@ bool Inspector::on_scroll_event(GdkEventScroll *event) if (!currImage || !window) return false; + pinned = true; + bool alt = event->state & GDK_MOD1_MASK; int deviceScale = get_scale_factor(); int imW = currImage->imgBuffer.getWidth(); @@ -381,6 +383,7 @@ void Inspector::beginZoom(double x, double y) void Inspector::on_zoom_begin(GdkEventSequence *s) { double x, y; + pinned = true; if (gestureZoom->get_point(s, x, y)) beginZoom(x, y); }