Open inspector fullscreen and exploit monitor resolution, see #1474, #5591

- filecatalog.cc: add shortcuts
    'f' for image on full screen
    'Shift' 'f' for 100% crop on full screen
    (synchronization with mouse move as before with dual monitors)
- filepanel.cc: don't create inspector tab
- inspector.cc, inspector.h:
    create separate window for inspector
    scale image if requested
    exploit device scaling for full monitor resolution under macOS
This commit is contained in:
rfranke
2020-01-03 10:37:22 +01:00
parent fbc7455ead
commit c4e21438a1
4 changed files with 83 additions and 13 deletions

View File

@@ -42,6 +42,7 @@
#include "pathutils.h" #include "pathutils.h"
#include "thumbnail.h" #include "thumbnail.h"
#include "toolbar.h" #include "toolbar.h"
#include "inspector.h"
using namespace std; 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); return fileBrowser->keyPressed(event);
} }

View File

@@ -115,9 +115,9 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) ); Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) );
devLab->set_name ("LabelRightNotebook"); devLab->set_name ("LabelRightNotebook");
devLab->set_angle (90); devLab->set_angle (90);
Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); //Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) );
inspectLab->set_name ("LabelRightNotebook"); //inspectLab->set_name ("LabelRightNotebook");
inspectLab->set_angle (90); //inspectLab->set_angle (90);
Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) ); Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) );
filtLab->set_name ("LabelRightNotebook"); filtLab->set_name ("LabelRightNotebook");
filtLab->set_angle (90); filtLab->set_angle (90);
@@ -132,7 +132,7 @@ FilePanel::FilePanel () : parent(nullptr), error(0)
tpcPaned->pack2 (*history, true, false); tpcPaned->pack2 (*history, true, false);
rightNotebook->append_page (*sFilterPanel, *filtLab); rightNotebook->append_page (*sFilterPanel, *filtLab);
rightNotebook->append_page (*inspectorPanel, *inspectLab); //rightNotebook->append_page (*inspectorPanel, *inspectLab);
rightNotebook->append_page (*tpcPaned, *devLab); rightNotebook->append_page (*tpcPaned, *devLab);
//rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ... //rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ...
rightNotebook->append_page (*sExportPanel, *exportLab); rightNotebook->append_page (*sExportPanel, *exportLab);

View File

@@ -82,9 +82,16 @@ InspectorBuffer::~InspectorBuffer() {
// return deg; // return deg;
//} //}
Inspector::Inspector () : currImage(nullptr), zoom(0.0), active(false) Inspector::Inspector () : currImage(nullptr), scaled(false), active(false)
{ {
set_name("Inspector"); 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() Inspector::~Inspector()
@@ -92,6 +99,19 @@ Inspector::~Inspector()
deleteBuffers(); 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) 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 availableSize;
rtengine::Coord topLeft; rtengine::Coord topLeft;
rtengine::Coord dest(0, 0); rtengine::Coord dest(0, 0);
availableSize.x = win->get_width(); int deviceScale = get_scale_factor();
availableSize.y = win->get_height(); availableSize.x = win->get_width() * deviceScale;
availableSize.y = win->get_height() * deviceScale;
int imW = currImage->imgBuffer.getWidth(); int imW = currImage->imgBuffer.getWidth();
int imH = currImage->imgBuffer.getHeight(); int imH = currImage->imgBuffer.getHeight();
double scale = 1.0;
if (scaled) {
// reduce size of image to fit into window
scale = rtengine::min<double>(1.0, rtengine::min<double>((double)availableSize.x/imW, (double)availableSize.y/imH));
availableSize.x /= scale;
availableSize.y /= scale;
}
if (imW < availableSize.x) { if (imW < availableSize.x) {
// center the image in the available space along 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<Gtk::StyleContext> style = get_style_context(); Glib::RefPtr<Gtk::StyleContext> style = get_style_context();
// draw the background // 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); c = style->get_background_color (Gtk::STATE_FLAG_NORMAL);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
cr->set_line_width (0); cr->set_line_width (0);
cr->rectangle (0, 0, availableSize.x, availableSize.y); cr->rectangle (0, 0, availableSize.x, availableSize.y);
cr->fill (); cr->fill ();
*/ //*/
bool scaledImage = scaled && (imW > win->get_width() || imH > win->get_height());
if (deviceScale == 1 && !scaledImage) {
// standard drawing
currImage->imgBuffer.copySurface(win); 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<Gdk::Pixbuf> crop = Gdk::Pixbuf::create(currImage->imgBuffer.getSurface(), topLeft.x, topLeft.y, rtengine::min<int>(imW, availableSize.x), rtengine::min<int>(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 // draw the frame
c = style->get_border_color (Gtk::STATE_FLAG_NORMAL); c = style->get_border_color (Gtk::STATE_FLAG_NORMAL);
cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue()); cr->set_source_rgb (c.get_red(), c.get_green(), c.get_blue());
cr->set_line_width (1); cr->set_line_width (1);
cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1); cr->rectangle (0.5, 0.5, availableSize.x - 1, availableSize.y - 1);
cr->stroke (); cr->stroke ();
*/
} }
return true; return true;
@@ -309,7 +361,7 @@ void Inspector::setActive(bool state)
flushBuffers(); flushBuffers();
} }
active = state; //active = state;
} }

View File

@@ -47,12 +47,15 @@ private:
rtengine::Coord center; rtengine::Coord center;
std::vector<InspectorBuffer*> images; std::vector<InspectorBuffer*> images;
InspectorBuffer* currImage; InspectorBuffer* currImage;
double zoom; bool scaled;
bool active; bool active;
sigc::connection delayconn; sigc::connection delayconn;
Glib::ustring next_image_path; Glib::ustring next_image_path;
Gtk::Window window;
bool on_key_release(GdkEventKey *event);
bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override; bool on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr) override;
void deleteBuffers(); void deleteBuffers();
@@ -62,6 +65,11 @@ public:
Inspector(); Inspector();
~Inspector() override; ~Inspector() override;
/** @brief Show or hide window
* @param scaled fit image into window
*/
void showWindow(bool scaled);
/** @brief Mouse movement to a new position /** @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 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 * @param transform H/V flip and coarse rotation transformation