diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 109a1bb57..a283398ee 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -42,6 +42,7 @@ #include "pathutils.h" #include "thumbnail.h" #include "toolbar.h" +#include "inspector.h" using namespace std; @@ -2503,6 +2504,15 @@ bool FileCatalog::handleShortcutKey (GdkEventKey* event) } } + if (!ctrl && !alt) { + switch (event->keyval) { + case GDK_KEY_f: + case GDK_KEY_F: + fileBrowser->getInspector()->showWindow(!shift); + return true; + } + } + return fileBrowser->keyPressed(event); } diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc index 1a66aed7c..983a0840c 100644 --- a/rtgui/filepanel.cc +++ b/rtgui/filepanel.cc @@ -115,9 +115,9 @@ FilePanel::FilePanel () : parent(nullptr), error(0) Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) ); devLab->set_name ("LabelRightNotebook"); devLab->set_angle (90); - Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); - inspectLab->set_name ("LabelRightNotebook"); - inspectLab->set_angle (90); + //Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); + //inspectLab->set_name ("LabelRightNotebook"); + //inspectLab->set_angle (90); Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) ); filtLab->set_name ("LabelRightNotebook"); filtLab->set_angle (90); @@ -132,7 +132,7 @@ FilePanel::FilePanel () : parent(nullptr), error(0) tpcPaned->pack2 (*history, true, false); rightNotebook->append_page (*sFilterPanel, *filtLab); - rightNotebook->append_page (*inspectorPanel, *inspectLab); + //rightNotebook->append_page (*inspectorPanel, *inspectLab); rightNotebook->append_page (*tpcPaned, *devLab); //rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ... rightNotebook->append_page (*sExportPanel, *exportLab); diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc index 9002cc389..d27dd8d08 100644 --- a/rtgui/inspector.cc +++ b/rtgui/inspector.cc @@ -82,9 +82,16 @@ InspectorBuffer::~InspectorBuffer() { // return deg; //} -Inspector::Inspector () : currImage(nullptr), zoom(0.0), active(false) +Inspector::Inspector () : currImage(nullptr), scaled(false), active(false) { set_name("Inspector"); + window.add_events(Gdk::KEY_PRESS_MASK); + window.signal_key_release_event().connect(sigc::mem_fun(*this, &Inspector::on_key_release)); + window.set_title("RawTherapee Inspector"); + window.add(*this); + window.show_all(); + window.set_visible(false); + active = true; // always track inspected thumbnails } Inspector::~Inspector() @@ -92,6 +99,19 @@ Inspector::~Inspector() deleteBuffers(); } +void Inspector::showWindow(bool scaled) +{ + this->scaled = scaled; + window.fullscreen(); + window.set_visible(true); +} + +bool Inspector::on_key_release(GdkEventKey *event) +{ + window.set_visible(false); + return true; +} + bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) { @@ -116,10 +136,18 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) rtengine::Coord availableSize; rtengine::Coord topLeft; rtengine::Coord dest(0, 0); - availableSize.x = win->get_width(); - availableSize.y = win->get_height(); + int deviceScale = get_scale_factor(); + availableSize.x = win->get_width() * deviceScale; + availableSize.y = win->get_height() * deviceScale; int imW = currImage->imgBuffer.getWidth(); int imH = currImage->imgBuffer.getHeight(); + double scale = 1.0; + if (scaled) { + // reduce size of image to fit into window + scale = rtengine::min(1.0, rtengine::min((double)availableSize.x/imW, (double)availableSize.y/imH)); + availableSize.x /= scale; + availableSize.y /= scale; + } if (imW < availableSize.x) { // center the image in the available space along X @@ -163,24 +191,48 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) Glib::RefPtr style = get_style_context(); // draw the background - style->render_background(cr, 0, 0, get_width(), get_height()); + //style->render_background(cr, 0, 0, get_width(), get_height()); - /* --- old method + ///* --- 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 (); - */ + //*/ - currImage->imgBuffer.copySurface(win); + bool scaledImage = scaled && (imW > win->get_width() || imH > win->get_height()); + if (deviceScale == 1 && !scaledImage) { + // standard drawing + currImage->imgBuffer.copySurface(win); + } + else { + // consider device scale and image scale + if (deviceScale > 1) { + // use full device resolution and let it scale the image (macOS) + cairo_surface_set_device_scale(cr->get_target()->cobj(), scale, scale); + scaledImage = false; + } + Glib::RefPtr crop = Gdk::Pixbuf::create(currImage->imgBuffer.getSurface(), topLeft.x, topLeft.y, rtengine::min(imW, availableSize.x), rtengine::min(imH, availableSize.y)); + if (!scaledImage) { + Gdk::Cairo::set_source_pixbuf(cr, crop, dest.x, dest.y); + } + else { + // assume that the device does not support scaling (Linux) + crop = crop->scale_simple(imW*scale, imH*scale, Gdk::INTERP_BILINEAR); + Gdk::Cairo::set_source_pixbuf(cr, crop, dest.x*scale, dest.y*scale); + } + cr->paint(); + } + /* --- not for separate window // draw the frame c = style->get_border_color (Gtk::STATE_FLAG_NORMAL); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); cr->set_line_width (1); cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1); cr->stroke (); + */ } return true; @@ -309,7 +361,7 @@ void Inspector::setActive(bool state) flushBuffers(); } - active = state; + //active = state; } diff --git a/rtgui/inspector.h b/rtgui/inspector.h index 8338259bf..2844b55ac 100644 --- a/rtgui/inspector.h +++ b/rtgui/inspector.h @@ -47,12 +47,15 @@ private: rtengine::Coord center; std::vector images; InspectorBuffer* currImage; - double zoom; + bool scaled; bool active; sigc::connection delayconn; Glib::ustring next_image_path; + Gtk::Window window; + bool on_key_release(GdkEventKey *event); + bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; void deleteBuffers(); @@ -62,6 +65,11 @@ public: Inspector(); ~Inspector() override; + /** @brief Show or hide window + * @param scaled fit image into window + */ + void showWindow(bool scaled); + /** @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