diff --git a/data/pref.xml b/data/pref.xml
index ae8c27c9b..5bd153c7b 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -112,6 +112,11 @@
+
+
+
+
+
@@ -335,6 +340,8 @@
+
+
diff --git a/data/strings/en.ini b/data/strings/en.ini
index 8252efce5..13f1a83e3 100644
--- a/data/strings/en.ini
+++ b/data/strings/en.ini
@@ -1079,6 +1079,10 @@ invalid_fg_bg_color_alert = Show alert when drawing with index out of palette bo
run_script_alert = Show alert when we try to run a script
reset_alerts = Reset all alert dialogs
color_management = Color Management
+window_cs = Window Color Profile
+use_monitor_cs = Use Current Monitor Color Profile
+use_srgb_cs = Use sRGB Color Profile
+use_specific_cs = Use {0}
working_rgb_cs = Working RGB space:
files_with_cs = Files with profile:
missing_cs = Missing profile:
diff --git a/data/widgets/options.xml b/data/widgets/options.xml
index adab9093c..b7f58abfd 100644
--- a/data/widgets/options.xml
+++ b/data/widgets/options.xml
@@ -126,6 +126,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/laf b/laf
index f3222bdee..952abae5d 160000
--- a/laf
+++ b/laf
@@ -1 +1 @@
-Subproject commit f3222bdee2d21556e9da55343e73803c730ecd97
+Subproject commit 952abae5d9534176e4cf15b4809fc5e9b4c02f0d
diff --git a/src/app/commands/cmd_options.cpp b/src/app/commands/cmd_options.cpp
index 343d82e6f..78ec0a86a 100644
--- a/src/app/commands/cmd_options.cpp
+++ b/src/app/commands/cmd_options.cpp
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2018 Igara Studio S.A.
+// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -19,6 +19,7 @@
#include "app/i18n/strings.h"
#include "app/ini_file.h"
#include "app/launcher.h"
+#include "app/modules/gui.h"
#include "app/pref/preferences.h"
#include "app/recent_files.h"
#include "app/resource_finder.h"
@@ -33,24 +34,26 @@
#include "base/version.h"
#include "doc/image.h"
#include "fmt/format.h"
-#include "render/render.h"
#include "os/display.h"
#include "os/system.h"
+#include "render/render.h"
#include "ui/ui.h"
#include "options.xml.h"
namespace app {
-static const char* kSectionGeneralId = "section_general";
-static const char* kSectionBgId = "section_bg";
-static const char* kSectionGridId = "section_grid";
-static const char* kSectionThemeId = "section_theme";
-static const char* kSectionExtensionsId = "section_extensions";
+namespace {
-static const char* kInfiniteSymbol = "\xE2\x88\x9E"; // Infinite symbol (UTF-8)
+const char* kSectionGeneralId = "section_general";
+const char* kSectionBgId = "section_bg";
+const char* kSectionGridId = "section_grid";
+const char* kSectionThemeId = "section_theme";
+const char* kSectionExtensionsId = "section_extensions";
-static app::gen::ColorProfileBehavior filesWithCsMap[] = {
+const char* kInfiniteSymbol = "\xE2\x88\x9E"; // Infinite symbol (UTF-8)
+
+app::gen::ColorProfileBehavior filesWithCsMap[] = {
app::gen::ColorProfileBehavior::DISABLE,
app::gen::ColorProfileBehavior::EMBEDDED,
app::gen::ColorProfileBehavior::CONVERT,
@@ -58,12 +61,14 @@ static app::gen::ColorProfileBehavior filesWithCsMap[] = {
app::gen::ColorProfileBehavior::ASK,
};
-static app::gen::ColorProfileBehavior missingCsMap[] = {
+app::gen::ColorProfileBehavior missingCsMap[] = {
app::gen::ColorProfileBehavior::DISABLE,
app::gen::ColorProfileBehavior::ASSIGN,
app::gen::ColorProfileBehavior::ASK,
};
+} // anonymous namespace
+
using namespace ui;
class OptionsWindow : public app::gen::Options {
@@ -179,6 +184,10 @@ public:
recentFiles()->setValue(m_pref.general.recentItems());
clearRecentFiles()->Click.connect(base::Bind(&OptionsWindow::onClearRecentFiles, this));
+ // Template item for active display color profiles
+ m_templateTextForDisplayCS = windowCs()->getItem(2)->text();
+ windowCs()->deleteItem(2);
+
// Color profiles
resetColorManagement()->Click.connect(base::Bind(&OptionsWindow::onResetColorManagement, this));
colorManagement()->Click.connect(base::Bind(&OptionsWindow::onColorManagement, this));
@@ -189,6 +198,8 @@ public:
workingRgbCs()->addItem(new ColorSpaceItem(cs));
}
updateColorProfileControls(m_pref.color.manage(),
+ m_pref.color.windowProfile(),
+ m_pref.color.windowProfileName(),
m_pref.color.workingRgbSpace(),
m_pref.color.filesWithProfile(),
m_pref.color.missingProfile());
@@ -498,6 +509,39 @@ public:
m_pref.color.missingProfile(
missingCsMap[missingCs()->getSelectedItemIndex()]);
+ int winCs = windowCs()->getSelectedItemIndex();
+ switch (winCs) {
+ case 0:
+ m_pref.color.windowProfile(gen::WindowColorProfile::MONITOR);
+ break;
+ case 1:
+ m_pref.color.windowProfile(gen::WindowColorProfile::SRGB);
+ break;
+ default: {
+ m_pref.color.windowProfile(gen::WindowColorProfile::SPECIFIC);
+
+ std::string name;
+ int j = 2;
+ for (auto& cs : m_colorSpaces) {
+ // We add ICC profiles only
+ auto gfxCs = cs->gfxColorSpace();
+ if (gfxCs->type() != gfx::ColorSpace::ICC)
+ continue;
+
+ if (j == winCs) {
+ name = gfxCs->name();
+ os::instance()->setDisplaysColorSpace(cs);
+ break;
+ }
+ ++j;
+ }
+
+ m_pref.color.windowProfileName(name);
+ break;
+ }
+ }
+ update_displays_color_profile_from_preferences();
+
m_curPref->show.grid(gridVisible()->isSelected());
m_curPref->grid.bounds(gridBounds());
m_curPref->grid.color(gridColor()->getColor());
@@ -707,6 +751,8 @@ private:
void onColorManagement() {
const bool state = colorManagement()->isSelected();
+ windowCsLabel()->setEnabled(state);
+ windowCs()->setEnabled(state);
workingRgbCsLabel()->setEnabled(state);
workingRgbCs()->setEnabled(state);
filesWithCsLabel()->setEnabled(state);
@@ -717,17 +763,53 @@ private:
void onResetColorManagement() {
updateColorProfileControls(m_pref.color.manage.defaultValue(),
+ m_pref.color.windowProfile.defaultValue(),
+ m_pref.color.windowProfileName.defaultValue(),
m_pref.color.workingRgbSpace.defaultValue(),
m_pref.color.filesWithProfile.defaultValue(),
m_pref.color.missingProfile.defaultValue());
}
void updateColorProfileControls(const bool manage,
+ const app::gen::WindowColorProfile& windowProfile,
+ const std::string& windowProfileName,
const std::string& workingRgbSpace,
const app::gen::ColorProfileBehavior& filesWithProfile,
const app::gen::ColorProfileBehavior& missingProfile) {
colorManagement()->setSelected(manage);
+ // Window color profile
+ {
+ int i = 0;
+ if (windowProfile == gen::WindowColorProfile::MONITOR)
+ i = 0;
+ else if (windowProfile == gen::WindowColorProfile::SRGB)
+ i = 1;
+
+ // Delete previous added items in the combobox for each display
+ // (we'll re-add them below).
+ while (windowCs()->getItem(2))
+ windowCs()->deleteItem(2);
+
+ int j = 2;
+ for (auto& cs : m_colorSpaces) {
+ // We add ICC profiles only
+ auto gfxCs = cs->gfxColorSpace();
+ if (gfxCs->type() != gfx::ColorSpace::ICC)
+ continue;
+
+ auto name = gfxCs->name();
+ windowCs()->addItem(fmt::format(m_templateTextForDisplayCS, name));
+ if (windowProfile == gen::WindowColorProfile::SPECIFIC &&
+ windowProfileName == name) {
+ i = j;
+ }
+ ++j;
+ }
+ windowCs()->setSelectedItemIndex(i);
+ }
+
+ // Working color profile
for (auto child : *workingRgbCs()) {
if (child->text() == workingRgbSpace) {
workingRgbCs()->setSelectedItem(child);
@@ -1273,6 +1355,7 @@ private:
int m_restoreScreenScaling;
int m_restoreUIScaling;
std::vector m_colorSpaces;
+ std::string m_templateTextForDisplayCS;
};
class OptionsCommand : public Command {
diff --git a/src/app/modules/gui.cpp b/src/app/modules/gui.cpp
index d762c1276..3cb49919b 100644
--- a/src/app/modules/gui.cpp
+++ b/src/app/modules/gui.cpp
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2018 Igara Studio S.A.
+// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@@ -202,6 +202,8 @@ int init_module_gui()
// Set graphics options for next time
save_gui_config();
+ update_displays_color_profile_from_preferences();
+
return 0;
}
@@ -219,6 +221,44 @@ void exit_module_gui()
main_display->dispose();
}
+void update_displays_color_profile_from_preferences()
+{
+ auto system = os::instance();
+
+ gen::WindowColorProfile windowProfile;
+ if (Preferences::instance().color.manage())
+ windowProfile = Preferences::instance().color.windowProfile();
+ else
+ windowProfile = gen::WindowColorProfile::SRGB;
+
+ switch (windowProfile) {
+ case gen::WindowColorProfile::MONITOR:
+ system->setDisplaysColorSpace(nullptr);
+ break;
+ case gen::WindowColorProfile::SRGB:
+ system->setDisplaysColorSpace(
+ system->createColorSpace(gfx::ColorSpace::MakeSRGB()));
+ break;
+ case gen::WindowColorProfile::SPECIFIC: {
+ std::string name =
+ Preferences::instance().color.windowProfileName();
+
+ std::vector colorSpaces;
+ system->listColorSpaces(colorSpaces);
+
+ for (auto& cs : colorSpaces) {
+ auto gfxCs = cs->gfxColorSpace();
+ if (gfxCs->type() == gfx::ColorSpace::ICC &&
+ gfxCs->name() == name) {
+ system->setDisplaysColorSpace(cs);
+ break;
+ }
+ }
+ break;
+ }
+ }
+}
+
static void load_gui_config(int& w, int& h, bool& maximized,
std::string& windowLayout)
{
diff --git a/src/app/modules/gui.h b/src/app/modules/gui.h
index e7b88804c..4dabeacef 100644
--- a/src/app/modules/gui.h
+++ b/src/app/modules/gui.h
@@ -1,5 +1,5 @@
// Aseprite
-// Copyright (C) 2018 Igara Studio S.A.
+// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
@@ -35,6 +35,7 @@ namespace app {
int init_module_gui();
void exit_module_gui();
+ void update_displays_color_profile_from_preferences();
void update_screen_for_document(const Doc* document);
void load_window_pos(ui::Widget* window, const char* section,
diff --git a/src/app/script/values.cpp b/src/app/script/values.cpp
index 012275ef4..a301f1430 100644
--- a/src/app/script/values.cpp
+++ b/src/app/script/values.cpp
@@ -161,6 +161,7 @@ FOR_ENUM(app::gen::SelectionMode)
FOR_ENUM(app::gen::StopAtGrid)
FOR_ENUM(app::gen::SymmetryMode)
FOR_ENUM(app::gen::TimelinePosition)
+FOR_ENUM(app::gen::WindowColorProfile)
FOR_ENUM(app::tools::FreehandAlgorithm)
FOR_ENUM(app::tools::InkType)
FOR_ENUM(app::tools::RotationAlgorithm)