Creates an RTImage cache
Fixes: - Fixes GUI issue on Windows (GDI handles limit reached) - Fixes an incorrect icon name in Perspective tool - Adds robustness RTScalable::loadSurfaceFromIcon function
This commit is contained in:
@@ -120,7 +120,7 @@ PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("
|
||||
RTImage* const ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small"));
|
||||
RTImage* const ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-small"));
|
||||
|
||||
RTImage* const ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-botton", Gtk::ICON_SIZE_BUTTON));
|
||||
RTImage* const ipers_auto_pitch = Gtk::manage (new RTImage ("perspective-vertical-bottom", Gtk::ICON_SIZE_BUTTON));
|
||||
RTImage* const ipers_auto_yaw = Gtk::manage (new RTImage ("perspective-horizontal-left", Gtk::ICON_SIZE_BUTTON));
|
||||
RTImage* const ipers_auto_pitch_yaw = Gtk::manage (new RTImage ("perspective-horizontal-vertical", Gtk::ICON_SIZE_BUTTON));
|
||||
|
||||
|
@@ -21,21 +21,95 @@
|
||||
|
||||
#include "rtimage.h"
|
||||
|
||||
#include "rtsurface.h"
|
||||
|
||||
std::map<std::pair<Glib::ustring, Gtk::IconSize>, std::shared_ptr<RTSurface>> RTImageCache::cache;
|
||||
|
||||
std::shared_ptr<RTSurface> RTImageCache::getCachedSurface(const Glib::ustring &icon_name, const Gtk::IconSize icon_size)
|
||||
{
|
||||
// Look for an existing cached icon
|
||||
const auto key = std::pair<Glib::ustring, Gtk::IconSize>(icon_name, icon_size);
|
||||
const auto item = cache.find(key);
|
||||
|
||||
if (item != cache.end()) { // A cached icon exists
|
||||
return item->second;
|
||||
} else { // Create the icon
|
||||
auto surface = std::shared_ptr<RTSurface>(new RTSurface(icon_name, icon_size));
|
||||
|
||||
// Add the surface to the cache if the icon exist
|
||||
if (surface) {
|
||||
cache.insert({key, surface});
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
}
|
||||
|
||||
void RTImageCache::updateCache()
|
||||
{
|
||||
// Iterate over cache to updated RTSurface
|
||||
for (auto const& item : cache) {
|
||||
item.second->updateSurface();
|
||||
}
|
||||
}
|
||||
|
||||
RTImage::RTImage () {}
|
||||
|
||||
RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) :
|
||||
Gtk::Image(iconName, iconSize),
|
||||
size(iconSize)
|
||||
Gtk::Image(),
|
||||
size(iconSize),
|
||||
icon_name(iconName)
|
||||
{
|
||||
// Set surface from icon cache
|
||||
surface = RTImageCache::getCachedSurface(this->icon_name, this->size);
|
||||
|
||||
// Add it to the RTImage if surface exists
|
||||
if (surface) {
|
||||
set(surface->get());
|
||||
}
|
||||
}
|
||||
|
||||
void RTImage::set_from_icon_name(const Glib::ustring& iconName)
|
||||
{
|
||||
Gtk::Image::set_from_icon_name(iconName, this->size);
|
||||
this->icon_name = iconName;
|
||||
|
||||
// Set surface from icon cache
|
||||
surface = RTImageCache::getCachedSurface(this->icon_name, this->size);
|
||||
|
||||
// Add it to the RTImage if surface exists
|
||||
if (surface) {
|
||||
set(surface->get());
|
||||
}
|
||||
}
|
||||
|
||||
void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize)
|
||||
{
|
||||
this->icon_name = iconName;
|
||||
this->size = iconSize;
|
||||
Gtk::Image::set_from_icon_name(iconName, this->size);
|
||||
|
||||
// Set surface from icon cache
|
||||
surface = RTImageCache::getCachedSurface(this->icon_name, this->size);
|
||||
|
||||
// Add it to the RTImage if surface exists
|
||||
if (surface) {
|
||||
set(surface->get());
|
||||
}
|
||||
}
|
||||
|
||||
int RTImage::get_width()
|
||||
{
|
||||
if (surface) {
|
||||
return surface->getWidth();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int RTImage::get_height()
|
||||
{
|
||||
if (surface) {
|
||||
return surface->getHeight();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@@ -20,7 +20,18 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gtkmm/image.h>
|
||||
#include <gtkmm.h>
|
||||
|
||||
class RTSurface;
|
||||
class RTImageCache final
|
||||
{
|
||||
private:
|
||||
static std::map<std::pair<Glib::ustring, Gtk::IconSize>, std::shared_ptr<RTSurface>> cache;
|
||||
|
||||
public:
|
||||
static std::shared_ptr<RTSurface> getCachedSurface(const Glib::ustring &icon_name, const Gtk::IconSize icon_size);
|
||||
static void updateCache();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A derived class of Gtk::Image in order to handle theme-related icon sets.
|
||||
@@ -29,6 +40,8 @@ class RTImage final : public Gtk::Image
|
||||
{
|
||||
private:
|
||||
Gtk::IconSize size;
|
||||
Glib::ustring icon_name;
|
||||
std::shared_ptr<RTSurface> surface;
|
||||
|
||||
public:
|
||||
RTImage ();
|
||||
@@ -36,4 +49,7 @@ public:
|
||||
|
||||
void set_from_icon_name(const Glib::ustring& iconName);
|
||||
void set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize);
|
||||
|
||||
int get_width();
|
||||
int get_height();
|
||||
};
|
||||
|
@@ -68,10 +68,22 @@ Cairo::RefPtr<Cairo::ImageSurface> RTScalable::loadSurfaceFromIcon(const Glib::u
|
||||
|
||||
// Looking for corresponding icon (if existing)
|
||||
const auto iconInfo = theme->lookup_icon(iconName, size);
|
||||
|
||||
if (!iconInfo) {
|
||||
if (rtengine::settings->verbose) {
|
||||
std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl;
|
||||
}
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
const auto iconPath = iconInfo.get_filename();
|
||||
|
||||
if ((iconPath.empty() || !iconInfo) && rtengine::settings->verbose) {
|
||||
if (iconPath.empty()) {
|
||||
if (rtengine::settings->verbose) {
|
||||
std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl;
|
||||
}
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
|
@@ -161,6 +161,19 @@ Cairo::RefPtr<Cairo::ImageSurface> RTSurface::get()
|
||||
{
|
||||
if (dpiBack != RTScalable::getDPI() ||
|
||||
scaleBack != RTScalable::getScale()) {
|
||||
updateSurface();
|
||||
|
||||
// Save new DPI and scale
|
||||
dpiBack = RTScalable::getDPI();
|
||||
scaleBack = RTScalable::getScale();
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
void RTSurface::updateSurface()
|
||||
{
|
||||
// Update surface based on the scale
|
||||
switch (type) {
|
||||
case RTSurface::IconType :
|
||||
surface = RTScalable::loadSurfaceFromIcon(name, icon_size);
|
||||
@@ -174,11 +187,4 @@ Cairo::RefPtr<Cairo::ImageSurface> RTSurface::get()
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
// Save new DPI and scale
|
||||
dpiBack = RTScalable::getDPI();
|
||||
scaleBack = RTScalable::getScale();
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
@@ -52,4 +52,5 @@ public:
|
||||
bool hasSurface();
|
||||
|
||||
Cairo::RefPtr<Cairo::ImageSurface> get();
|
||||
void updateSurface();
|
||||
};
|
||||
|
Reference in New Issue
Block a user