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 ipersVL = Gtk::manage (new RTImage ("perspective-vertical-bottom-small"));
|
||||||
RTImage* const ipersVR = Gtk::manage (new RTImage ("perspective-vertical-top-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_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));
|
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 "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 () {}
|
||||||
|
|
||||||
RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) :
|
RTImage::RTImage (const Glib::ustring& iconName, const Gtk::IconSize iconSize) :
|
||||||
Gtk::Image(iconName, iconSize),
|
Gtk::Image(),
|
||||||
size(iconSize)
|
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)
|
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)
|
void RTImage::set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize)
|
||||||
{
|
{
|
||||||
|
this->icon_name = iconName;
|
||||||
this->size = iconSize;
|
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
|
#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.
|
* @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:
|
private:
|
||||||
Gtk::IconSize size;
|
Gtk::IconSize size;
|
||||||
|
Glib::ustring icon_name;
|
||||||
|
std::shared_ptr<RTSurface> surface;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RTImage ();
|
RTImage ();
|
||||||
@@ -36,4 +49,7 @@ public:
|
|||||||
|
|
||||||
void set_from_icon_name(const Glib::ustring& iconName);
|
void set_from_icon_name(const Glib::ustring& iconName);
|
||||||
void set_from_icon_name(const Glib::ustring& iconName, const Gtk::IconSize iconSize);
|
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)
|
// Looking for corresponding icon (if existing)
|
||||||
const auto iconInfo = theme->lookup_icon(iconName, size);
|
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();
|
const auto iconPath = iconInfo.get_filename();
|
||||||
|
|
||||||
if ((iconPath.empty() || !iconInfo) && rtengine::settings->verbose) {
|
if (iconPath.empty()) {
|
||||||
std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl;
|
if (rtengine::settings->verbose) {
|
||||||
|
std::cerr << "Failed to load icon \"" << iconName << "\" for size " << size << "px" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return surf;
|
return surf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -161,19 +161,7 @@ Cairo::RefPtr<Cairo::ImageSurface> RTSurface::get()
|
|||||||
{
|
{
|
||||||
if (dpiBack != RTScalable::getDPI() ||
|
if (dpiBack != RTScalable::getDPI() ||
|
||||||
scaleBack != RTScalable::getScale()) {
|
scaleBack != RTScalable::getScale()) {
|
||||||
switch (type) {
|
updateSurface();
|
||||||
case RTSurface::IconType :
|
|
||||||
surface = RTScalable::loadSurfaceFromIcon(name, icon_size);
|
|
||||||
break;
|
|
||||||
case RTSurface::PNGType :
|
|
||||||
surface = RTScalable::loadSurfaceFromPNG(name);
|
|
||||||
break;
|
|
||||||
case RTSurface::SVGType :
|
|
||||||
surface = RTScalable::loadSurfaceFromSVG(name);
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save new DPI and scale
|
// Save new DPI and scale
|
||||||
dpiBack = RTScalable::getDPI();
|
dpiBack = RTScalable::getDPI();
|
||||||
@@ -182,3 +170,21 @@ Cairo::RefPtr<Cairo::ImageSurface> RTSurface::get()
|
|||||||
|
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RTSurface::updateSurface()
|
||||||
|
{
|
||||||
|
// Update surface based on the scale
|
||||||
|
switch (type) {
|
||||||
|
case RTSurface::IconType :
|
||||||
|
surface = RTScalable::loadSurfaceFromIcon(name, icon_size);
|
||||||
|
break;
|
||||||
|
case RTSurface::PNGType :
|
||||||
|
surface = RTScalable::loadSurfaceFromPNG(name);
|
||||||
|
break;
|
||||||
|
case RTSurface::SVGType :
|
||||||
|
surface = RTScalable::loadSurfaceFromSVG(name);
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -52,4 +52,5 @@ public:
|
|||||||
bool hasSurface();
|
bool hasSurface();
|
||||||
|
|
||||||
Cairo::RefPtr<Cairo::ImageSurface> get();
|
Cairo::RefPtr<Cairo::ImageSurface> get();
|
||||||
|
void updateSurface();
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user