Implement first draft for custom color palette

- using .gpl file format config file
wilder/unmaintained
idotobi 5 years ago committed by Jacopo De Simoi
parent f791e02ed1
commit f3d406beb7
  1. 1
      CMakeLists.txt
  2. 7
      src/config-dev.h.in
  3. 2
      src/control/Control.h
  4. 7
      src/control/XournalMain.cpp
  5. 11
      src/control/settings/Settings.cpp
  6. 5
      src/control/settings/Settings.h
  7. 34
      src/gui/dialog/toolbarCustomize/CustomizeableColorList.cpp
  8. 34
      src/gui/dialog/toolbarCustomize/CustomizeableColorList.h
  9. 8
      src/gui/dialog/toolbarCustomize/ToolbarAdapter.cpp
  10. 67
      src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.cpp
  11. 3
      src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.h
  12. 15
      src/gui/toolbarMenubar/ColorToolItem.cpp
  13. 3
      src/gui/toolbarMenubar/ColorToolItem.h
  14. 20
      src/gui/toolbarMenubar/ToolMenuHandler.cpp
  15. 2
      src/gui/toolbarMenubar/ToolMenuHandler.h
  16. 132
      src/gui/toolbarMenubar/model/ColorPalette.cpp
  17. 35
      src/gui/toolbarMenubar/model/ColorPalette.h
  18. 105
      src/gui/toolbarMenubar/model/ToolbarColorNames.cpp
  19. 45
      src/gui/toolbarMenubar/model/ToolbarColorNames.h
  20. 7
      src/util/Color.h
  21. 33
      src/util/NamedColor.cpp
  22. 11
      src/util/NamedColor.h

@ -204,6 +204,7 @@ mark_as_advanced (FORCE
# Advanced development config
set (DEV_TOOLBAR_CONFIG "toolbar.ini" CACHE STRING "Toolbar config file name")
set (DEV_SETTINGS_XML_FILE "settings.xml" CACHE STRING "Settings file name")
set (DEV_PALETTE_FILE "palette.gpl" CACHE STRING "Color Palette")
set (DEV_PRINT_CONFIG_FILE "print-config.ini" CACHE STRING "Print config file name")
set (DEV_METADATA_FILE "metadata.ini" CACHE STRING "Metadata file name")
set (DEV_METADATA_MAX_ITEMS 50 CACHE STRING "Maximal amount of metadata elements")

@ -21,6 +21,11 @@
*/
#define SETTINGS_XML_FILE "@DEV_SETTINGS_XML_FILE@"
/**
* Gimp Palette File
*/
#define PALETTE_FILE "@DEV_PALETTE_FILE@"
/**
* Print config file name
*/
@ -34,7 +39,7 @@
/**
* Maximal amount of metadata elements
*/
#define METADATA_MAX_ITEMS @DEV_METADATA_MAX_ITEMS@
#define METADATA_MAX_ITEMS @DEV_METADATA_MAX_ITEMS @
/**
* Directory where errorlogfiles will be placed

@ -18,6 +18,7 @@
#include "gui/MainWindow.h"
#include "gui/SearchBar.h"
#include "gui/sidebar/Sidebar.h"
#include "gui/toolbarMenubar/model/ColorPalette.h"
#include "jobs/ProgressListener.h"
#include "jobs/XournalScheduler.h"
#include "model/Document.h"
@ -337,6 +338,7 @@ private:
ZoomControl* zoom;
Settings* settings;
Palette* palette;
MainWindow* win = nullptr;
Document* doc = nullptr;

@ -11,7 +11,6 @@
#include "gui/GladeSearchpath.h"
#include "gui/MainWindow.h"
#include "gui/XournalView.h"
#include "gui/toolbarMenubar/model/ToolbarColorNames.h"
#include "pdf/base/XojPdfExport.h"
#include "pdf/base/XojPdfExportFactory.h"
#include "undo/EmergencySaveRestore.h"
@ -345,9 +344,6 @@ auto XournalMain::run(int argc, char* argv[]) -> int {
initResourcePath(gladePath, "ui/xournalpp.css",
false); // will notify user if file not present. Path ui/ already added above.
// init singleton
auto colorNameFile = Util::getConfigFile("colornames.ini");
ToolbarColorNames::getInstance().loadFile(colorNameFile);
auto* control = new Control(gladePath);
@ -424,9 +420,6 @@ auto XournalMain::run(int argc, char* argv[]) -> int {
delete control;
delete gladePath;
ToolbarColorNames::getInstance().saveFile(colorNameFile);
ToolbarColorNames::freeInstance();
return 0;
}

@ -2,6 +2,8 @@
#include <utility>
#include <PathUtil.h>
#include "model/FormatDefinitions.h"
#include "util/DeviceListHelper.h"
@ -596,6 +598,15 @@ auto Settings::load() -> bool {
loadButtonConfig();
loadDeviceClasses();
paletteFilePath = PALETTE_FILE;
auto paletteFile = Util::getConfigFile(paletteFilePath);
if (!fs::exists(paletteFile)) {
Palette::create_default(paletteFile);
}
this->palette = new Palette(std::move(paletteFile));
this->palette->load();
// load Palette
return true;
}

@ -15,6 +15,7 @@
#include <memory>
#include <config-dev.h>
#include <gui/toolbarMenubar/model/ColorPalette.h>
#include <libxml/xmlreader.h>
#include <portaudio.h>
@ -895,4 +896,8 @@ private:
* e.g. "en_US"
*/
std::string preferredLocale;
public:
Palette* palette;
fs::path paletteFilePath;
};

@ -1,34 +0,0 @@
#include "CustomizeableColorList.h"
#include <utility>
#include <config.h>
#include "i18n.h"
CustomizeableColorList::CustomizeableColorList() {
this->addPredefinedColor(0x000000U, _("Black"));
this->addPredefinedColor(0x008000U, _("Green"));
this->addPredefinedColor(0x00c0ffU, _("Light Blue"));
this->addPredefinedColor(0x00ff00U, _("Light Green"));
this->addPredefinedColor(0x3333ccU, _("Blue"));
this->addPredefinedColor(0x808080U, _("Gray"));
this->addPredefinedColor(0xff0000U, _("Red"));
this->addPredefinedColor(0xff00ffU, _("Magenta"));
this->addPredefinedColor(0xff8000U, _("Orange"));
this->addPredefinedColor(0xffff00U, _("Yellow"));
this->addPredefinedColor(0xffffffU, _("White"));
}
CustomizeableColorList::~CustomizeableColorList() {
for (XojColor* c: this->colors) {
delete c;
}
this->colors.clear();
}
auto CustomizeableColorList::getPredefinedColors() -> vector<XojColor*>* { return &this->colors; }
void CustomizeableColorList::addPredefinedColor(Color color, string name) {
this->colors.push_back(new XojColor(color, std::move(name)));
}

@ -1,34 +0,0 @@
/*
* Xournal++
*
* List of unused colors for toolbar customisation
*
* @author Xournal++ Team
* https://github.com/xournalpp/xournalpp
*
* @license GNU GPLv2 or later
*/
#pragma once
#include <string>
#include <vector>
#include "gui/XojColor.h"
#include "XournalType.h"
class CustomizeableColorList {
public:
CustomizeableColorList();
virtual ~CustomizeableColorList();
public:
vector<XojColor*>* getPredefinedColors();
private:
void addPredefinedColor(Color color, string name);
private:
vector<XojColor*> colors;
};

@ -279,8 +279,14 @@ void ToolbarAdapter::toolbarDragDataReceivedCb(GtkToolbar* toolbar, GdkDragConte
int newId = tb->insertItem(name, id, pos);
ToolitemDragDrop::attachMetadata(GTK_WIDGET(it), newId, d->item);
} else if (d->type == TOOL_ITEM_COLOR) {
// [idotobi]: TODO fix
auto palette = adapter->window->getControl()->getSettings()->palette;
auto namedColor = palette->getNext();
auto c = Util::colorU16_to_rgb(namedColor.color);
auto colorName = namedColor.name;
auto* item = new ColorToolItem(adapter->window->getControl(), adapter->window->getControl()->getToolHandler(),
GTK_WINDOW(adapter->window->getWindow()), d->color);
GTK_WINDOW(adapter->window->getWindow()), c, colorName);
bool horizontal = gtk_orientable_get_orientation(GTK_ORIENTABLE(toolbar)) == GTK_ORIENTATION_HORIZONTAL;
GtkToolItem* it = item->createItem(horizontal);

@ -2,15 +2,17 @@
#include <config.h>
#include "control/Control.h"
#include "gui/MainWindow.h"
#include "gui/toolbarMenubar/AbstractToolItem.h"
#include "gui/toolbarMenubar/ToolMenuHandler.h"
#include "gui/toolbarMenubar/icon/ColorSelectImage.h"
#include "gui/toolbarMenubar/icon/ToolbarSeparatorImage.h"
#include "gui/toolbarMenubar/model/ColorPalette.h"
#include "gui/toolbarMenubar/model/ToolbarData.h"
#include "gui/toolbarMenubar/model/ToolbarModel.h"
#include "util/Color.h"
#include "CustomizeableColorList.h"
#include "ToolItemDragCurrentData.h"
#include "ToolbarDragDropHandler.h"
#include "ToolbarDragDropHelper.h"
@ -31,7 +33,6 @@ ToolbarCustomizeDialog::ToolbarCustomizeDialog(GladeSearchpath* gladeSearchPath,
GladeGui(gladeSearchPath, "toolbarCustomizeDialog.glade", "DialogCustomizeToolbar") {
this->win = win;
this->handler = handler;
this->colorList = new CustomizeableColorList();
rebuildIconview();
rebuildColorIcons();
@ -84,9 +85,6 @@ ToolbarCustomizeDialog::~ToolbarCustomizeDialog() {
g_object_unref(data->icon);
g_free(data);
}
delete this->colorList;
this->colorList = nullptr;
}
void ToolbarCustomizeDialog::toolitemDragBeginSeparator(GtkWidget* widget, GdkDragContext* context, void* unused) {
@ -315,44 +313,49 @@ void ToolbarCustomizeDialog::rebuildColorIcons() {
freeColorIconview();
ToolMenuHandler* tmh = this->win->getToolMenuHandler();
Control* control = tmh->getControl();
Palette* palette = control->getSettings()->palette;
int i = 0;
for (XojColor* color: *this->colorList->getPredefinedColors()) {
if (tmh->isColorInUse(color->getColor())) {
continue;
}
// [idotobi]: cleanup
NamedColor namedColor = palette->getNext(0);
Color c = Util::colorU16_to_rgb(namedColor.color);
// if (tmh->isColorInUse(c)) {
// continue;
// }
GtkWidget* icon = ColorSelectImage::newColorIcon(color->getColor(), 16, true);
// GtkWidget* icon = ColorSelectImage::newColorIcon(color->getColor(), 16, true);
GtkWidget* icon = ColorSelectImage::newColorIcon(c, 16, true);
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
gtk_widget_show(box);
GtkWidget* label = gtk_label_new(color->getName().c_str());
gtk_widget_show(label);
gtk_box_pack_end(GTK_BOX(box), label, false, false, 0);
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 3);
gtk_widget_show(box);
GtkWidget* ebox = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(ebox), box);
gtk_widget_show(ebox);
GtkWidget* label = gtk_label_new(namedColor.name.c_str());
gtk_widget_show(label);
gtk_box_pack_end(GTK_BOX(box), label, false, false, 0);
gtk_widget_show(icon);
GtkWidget* ebox = gtk_event_box_new();
gtk_container_add(GTK_CONTAINER(ebox), box);
gtk_widget_show(ebox);
gtk_box_pack_end(GTK_BOX(box), icon, false, false, 0);
gtk_widget_show(icon);
// make ebox a drag source
gtk_drag_source_set(ebox, GDK_BUTTON1_MASK, &ToolbarDragDropHelper::dropTargetEntry, 1, GDK_ACTION_MOVE);
ToolbarDragDropHelper::dragSourceAddToolbar(ebox);
gtk_box_pack_end(GTK_BOX(box), icon, false, false, 0);
g_signal_connect(ebox, "drag-begin", G_CALLBACK(toolitemColorDragBegin), GUINT_TO_POINTER(color->getColor()));
g_signal_connect(ebox, "drag-end", G_CALLBACK(toolitemColorDragEnd), this);
g_signal_connect(ebox, "drag-data-get", G_CALLBACK(toolitemColorDragDataGet),
GUINT_TO_POINTER(color->getColor()));
// make ebox a drag source
gtk_drag_source_set(ebox, GDK_BUTTON1_MASK, &ToolbarDragDropHelper::dropTargetEntry, 1, GDK_ACTION_MOVE);
ToolbarDragDropHelper::dragSourceAddToolbar(ebox);
int x = i % 5;
int y = i / 5;
i++;
gtk_grid_attach(table, ebox, x, y, 1, 1);
}
g_signal_connect(ebox, "drag-begin", G_CALLBACK(toolitemColorDragBegin), GUINT_TO_POINTER(c));
g_signal_connect(ebox, "drag-end", G_CALLBACK(toolitemColorDragEnd), this);
g_signal_connect(ebox, "drag-data-get", G_CALLBACK(toolitemColorDragDataGet), GUINT_TO_POINTER(c));
int x = i % 5;
int y = i / 5;
i++;
gtk_grid_attach(table, ebox, x, y, 1, 1);
//}
gtk_widget_show_all(GTK_WIDGET(table));
}

@ -17,7 +17,6 @@
#include "gui/GladeGui.h"
#include "CustomizeableColorList.h"
#include "XournalType.h"
class AbstractToolItem;
@ -68,8 +67,6 @@ private:
static void windowResponseCb(GtkDialog* dialog, int response, ToolbarCustomizeDialog* dlg);
private:
CustomizeableColorList* colorList;
std::list<ToolItemDragData*> itemDatalist;
MainWindow* win;

@ -4,7 +4,6 @@
#include "control/ToolEnums.h"
#include "gui/toolbarMenubar/icon/ColorSelectImage.h"
#include "model/ToolbarColorNames.h"
#include "StringUtils.h"
#include "Util.h"
@ -13,14 +12,13 @@
bool ColorToolItem::inUpdate = false;
ColorToolItem::ColorToolItem(ActionHandler* handler, ToolHandler* toolHandler, GtkWindow* parent, Color color,
bool selektor):
string name, bool selektor):
AbstractToolItem("", handler, selektor ? ACTION_SELECT_COLOR_CUSTOM : ACTION_SELECT_COLOR),
color(color),
toolHandler(toolHandler),
parent(parent) {
parent(parent),
name{name} {
this->group = GROUP_COLOR;
updateName();
}
ColorToolItem::~ColorToolItem() { freeIcons(); }
@ -35,13 +33,6 @@ void ColorToolItem::freeIcons() {
auto ColorToolItem::isSelector() -> bool { return this->action == ACTION_SELECT_COLOR_CUSTOM; }
void ColorToolItem::updateName() {
if (this->action == ACTION_SELECT_COLOR_CUSTOM) {
this->name = _("Select color");
} else {
this->name = ToolbarColorNames::getInstance().getColorName(this->color);
}
}
void ColorToolItem::actionSelected(ActionGroup group, ActionType action) {
inUpdate = true;

@ -23,7 +23,7 @@ class ColorSelectImage;
class ColorToolItem: public AbstractToolItem {
public:
ColorToolItem(ActionHandler* handler, ToolHandler* toolHandler, GtkWindow* parent, Color color,
ColorToolItem(ActionHandler* handler, ToolHandler* toolHandler, GtkWindow* parent, Color color, string name,
bool selektor = false);
virtual ~ColorToolItem();
@ -46,7 +46,6 @@ public:
protected:
virtual GtkToolItem* newItem();
void updateName();
bool isSelector();
/**

@ -9,6 +9,7 @@
#include "control/Control.h"
#include "control/PageBackgroundChangeController.h"
#include "gui/ToolitemDragDrop.h"
#include "gui/toolbarMenubar/model/ColorPalette.h"
#include "model/ToolbarData.h"
#include "model/ToolbarModel.h"
@ -88,6 +89,9 @@ void ToolMenuHandler::unloadToolbar(GtkWidget* toolbar) {
void ToolMenuHandler::load(ToolbarData* d, GtkWidget* toolbar, const char* toolbarName, bool horizontal) {
int count = 0;
Palette* palette = this->control->getSettings()->palette;
palette->reset();
for (ToolbarEntry* e: d->contents) {
if (e->getName() == toolbarName) {
for (ToolbarItem* dataItem: e->getItems()) {
@ -133,10 +137,14 @@ void ToolMenuHandler::load(ToolbarData* d, GtkWidget* toolbar, const char* toolb
}
count++;
color = color.substr(2);
auto c = Color(g_ascii_strtoull(color.c_str(), nullptr, 16));
// color = color.substr(2);
// auto c = Color(g_ascii_strtoull(color.c_str(), nullptr, 16));
auto namedColor = palette->getNext();
auto c = Util::colorU16_to_rgb(namedColor.color);
auto colorName = namedColor.name;
auto* item = new ColorToolItem(listener, toolHandler, this->parent, c);
// [idotobi]: addition of ColotToolItem
auto* item = new ColorToolItem(listener, toolHandler, this->parent, c, colorName);
this->toolbarColorItems.push_back(item);
GtkToolItem* it = item->createItem(horizontal);
@ -193,6 +201,8 @@ void ToolMenuHandler::removeColorToolItem(AbstractToolItem* it) {
break;
}
}
// [idotobi]: find cleaner solution for this hack
this->control->getSettings()->palette->getNext(-1);
delete dynamic_cast<ColorToolItem*>(it);
}
@ -463,7 +473,7 @@ void ToolMenuHandler::initToolItems() {
// ************************************************************************
// Color item - not in the menu
addToolItem(new ColorToolItem(listener, toolHandler, this->parent, Color{0xff0000U}, true));
addToolItem(new ColorToolItem(listener, toolHandler, this->parent, Color{0xff0000U}, "Custom Color", true));
addToolItem(new ToolSelectCombocontrol(this, listener, "SELECT"));
addToolItem(new ToolDrawCombocontrol(this, listener, "DRAW"));
@ -504,6 +514,8 @@ void ToolMenuHandler::setPageText(const string& text) { this->toolPageSpinner->s
auto ToolMenuHandler::getModel() -> ToolbarModel* { return this->tbModel; }
auto ToolMenuHandler::getControl() -> Control* { return this->control; }
auto ToolMenuHandler::isColorInUse(Color color) -> bool {
for (ColorToolItem* it: this->toolbarColorItems) {
if (it->getColor() == color) {

@ -69,6 +69,8 @@ public:
vector<AbstractToolItem*>* getToolItems();
Control* getControl();
bool isColorInUse(Color color);
void disableAudioPlaybackButtons();

@ -0,0 +1,132 @@
#include "ColorPalette.h"
#include <fstream>
#include <limits>
#include <sstream>
#include <gtk/gtk.h>
#include <util/StringUtils.h>
Palette::Palette(fs::path path): filepath{std::move(path)}, header{}, colors{}, next{0} {}
void Palette::load() {
std::ifstream myfile{filepath};
std::string line;
Header h;
if (myfile.is_open()) {
getline(myfile, line);
line = StringUtils::trim(line);
if (line != "GIMP Palette") {
g_error(".gpt file needs to start with \"GIMP Palette\" in the "
"first line");
}
while (getline(myfile, line)) {
std::istringstream iss{line};
if (iss >> h) {
header[h.attribute] = h.value;
} else {
NamedColor color;
std::istringstream iss2{line};
if (iss2 >> color) {
colors.push_back(color);
}
}
}
}
}
NamedColor Palette::getNext(int inc) {
next += inc;
if (next >= colors.size()) {
next = 0;
g_warning("There are more Coloritems in the Toolbar then your Palette defines.\n"
"Hence, cycling through palette from the beginning.");
}
return colors.at(next);
}
void Palette::reset() { next = 0; };
void Palette::create_default(fs::path filepath) {
std::ofstream myfile{filepath};
myfile << "GIMP Palette"
<< "\n";
myfile << "Name: Xournal Default Palette"
<< "\n";
myfile << "#"
<< "\n";
myfile << 0 << " " << 0 << " " << 0 << " "
<< "Black"
<< "\n";
myfile << 0 << " " << 128 << " " << 0 << " "
<< "Green"
<< "\n";
myfile << 0 << " " << 192 << " " << 255 << " "
<< "Light Blue"
<< "\n";
myfile << 0 << " " << 255 << " " << 0 << " "
<< "Light Green"
<< "\n";
myfile << 51 << " " << 51 << " " << 204 << " "
<< "Blue"
<< "\n";
myfile << 128 << " " << 128 << " " << 128 << " "
<< "Gray"
<< "\n";
myfile << 255 << " " << 0 << " " << 0 << " "
<< "Red"
<< "\n";
myfile << 255 << " " << 0 << " " << 255 << " "
<< "Magenta"
<< "\n";
myfile << 255 << " " << 128 << " " << 0 << " "
<< "Orange"
<< "\n";
myfile << 255 << " " << 255 << " " << 0 << " "
<< "Yellow"
<< "\n";
myfile << 255 << " " << 255 << " " << 255 << " "
<< "White"
<< "\n";
}
std::istream& operator>>(std::istream& str, Header& data) {
std::string line;
Header tmp;
if (std::getline(str, line)) {
std::istringstream iss{line};
if (getline(iss, tmp.attribute, ':') && getline(iss, tmp.value, '\n')) {
tmp.attribute = StringUtils::trim(tmp.attribute);
tmp.value = StringUtils::trim(tmp.value);
/* OK: All read operations worked */
data.swap(tmp); // C++03 as this answer was written a long time ago.
} else {
// One operation failed.
// So set the state on the main stream
// to indicate failure.
str.setstate(std::ios::failbit);
}
}
return str;
}
void Header::swap(Header& other) // C++03 as this answer was written a long time ago.
{
std::swap(attribute, other.attribute);
std::swap(value, other.value);
}
// Default xournal
// 0 0 0 Black
// 0 128 0 Green
// 0 192 255 Light Blue
// 0 255 0 Light Green
// 51 51 204 Blue
// 128 128 128 Gray
// 255 0 0 Red
// 255 0 255 Magenta
// 255 128 0 Orange
// 255 255 0 Yellow
// 255 255 255 White

@ -0,0 +1,35 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include <filesystem.h>
#include <util/NamedColor.h>
struct Header {
// inspired by
// https://codereview.stackexchange.com/questions/38879/parsing-text-file-in-c
std::string attribute;
std::string value;
friend std::istream& operator>>(std::istream& str, Header& data);
void swap(Header& other);
};
struct Palette {
fs::path filepath;
int next;
std::map<std::string, std::string> header;
std::vector<NamedColor> colors;
Palette(fs::path path);
NamedColor getNext(int inc = 1);
void load();
void reset();
static void create_default(fs::path path);
};

@ -1,105 +0,0 @@
#include "ToolbarColorNames.h"
#include <fstream>
#include <glib/gstdio.h>
#include "i18n.h"
ToolbarColorNames::ToolbarColorNames() {
this->config = g_key_file_new();
g_key_file_set_string(this->config, "info", "about", "Xournalpp custom color names");
initPredefinedColors();
}
ToolbarColorNames::~ToolbarColorNames() {
g_key_file_free(this->config);
}
static ToolbarColorNames* instance = nullptr;
auto ToolbarColorNames::getInstance() -> ToolbarColorNames& {
if (instance == nullptr) {
instance = new ToolbarColorNames();
}
return *instance;
}
void ToolbarColorNames::freeInstance() {
delete instance;
instance = nullptr;
}
void ToolbarColorNames::loadFile(fs::path const& file) {
GError* error = nullptr;
if (!g_key_file_load_from_file(config, file.u8string().c_str(), G_KEY_FILE_NONE, &error)) {
g_warning("Failed to load \"colornames.ini\" (%s): %s\n", file.string().c_str(), error->message);
g_error_free(error);
return;
}
g_key_file_set_string(this->config, "info", "about", "Xournalpp custom color names");
}
void ToolbarColorNames::saveFile(fs::path const& file) {
gsize len = 0;
char* data = g_key_file_to_data(this->config, &len, nullptr);
try {
std::ofstream ofs{file, std::ios::binary};
ofs.exceptions(std::ios::badbit | std::ios::failbit);
ofs.write(data, len);
} catch (std::ios_base::failure const& e) {
g_warning("Could not save color file «%s».\n%s with error code %d", file.u8string().c_str(), e.what(),
e.code().value());
}
g_free(data);
}
void ToolbarColorNames::addColor(Color color, const std::string& name, bool predefined) {
if (predefined) {
this->predefinedColorNames[color] = name;
} else {
char colorHex[16];
sprintf(colorHex, "%06x", uint32_t{color});
g_key_file_set_string(this->config, "custom", colorHex, name.c_str());
}
}
auto ToolbarColorNames::getColorName(Color color) -> std::string {
char colorHex[16];
sprintf(colorHex, "%06x", uint32_t{color});
std::string colorName;
char* name = g_key_file_get_string(this->config, "custom", colorHex, nullptr);
if (name != nullptr) {
colorName = name;
g_free(name);
}
if (!colorName.empty()) {
return colorName;
}
if (auto iter = this->predefinedColorNames.find(color); iter != end(this->predefinedColorNames)) {
return iter->second;
}
return colorHex;
}
void ToolbarColorNames::initPredefinedColors() {
// Here you can add predefined color names
// this ordering fixes #2
addColor(0x000000U, _("Black"), true);
addColor(0x008000U, _("Green"), true);
addColor(0x00c0ffU, _("Light Blue"), true);
addColor(0x00ff00U, _("Light Green"), true);
addColor(0x3333ccU, _("Blue"), true);
addColor(0x808080U, _("Gray"), true);
addColor(0xff0000U, _("Red"), true);
addColor(0xff00ffU, _("Magenta"), true);
addColor(0xff8000U, _("Orange"), true);
addColor(0xffff00U, _("Yellow"), true);
addColor(0xffffffU, _("White"), true);
}

@ -1,45 +0,0 @@
/*
* Xournal++
*
* Names for the toolbar color items (e.g. 0xff000 is called red)
* Singleton
*
* @author Xournal++ Team
* https://github.com/xournalpp/xournalpp
*
* @license GNU GPLv2 or later
*/
#pragma once
#include <string>
#include <unordered_map>
#include "util/Color.h"
#include "filesystem.h"
class ToolbarColorNames {
private:
ToolbarColorNames();
virtual ~ToolbarColorNames();
public:
static ToolbarColorNames& getInstance();
static void freeInstance();
public:
void loadFile(fs::path const& file);
void saveFile(fs::path const& file);
void addColor(Color color, const std::string& name, bool predefined);
std::string getColorName(Color color);
private:
void initPredefinedColors();
private:
GKeyFile* config;
std::unordered_map<Color, std::string> predefinedColorNames{};
};

@ -97,6 +97,7 @@ constexpr auto argb_to_GdkRGBA(Color color) -> GdkRGBA;
constexpr auto argb_to_GdkRGBA(Color color, double alpha) -> GdkRGBA;
constexpr auto GdkRGBA_to_argb(const GdkRGBA& color) -> Color;
constexpr auto GdkRGBA_to_rgb(const GdkRGBA& color) -> Color;
constexpr auto colorU16_to_rgb(const ColorU16& color) -> Color;
constexpr auto GdkRGBA_to_ColorU16(const GdkRGBA& color) -> ColorU16;
@ -137,6 +138,12 @@ constexpr auto Util::GdkRGBA_to_rgb(const GdkRGBA& color) -> Color {
floatToUIntColor(color.blue);
}
constexpr auto Util::colorU16_to_rgb(const ColorU16& color) -> Color {
return color.red << 16U | //
color.blue << 8U | //
color.green;
}
constexpr auto Util::floatToUIntColor(const double color) -> uint32_t { //
// Splits the double into a equal sized distribution between [0,256[ and rounding down
// inspired by, which isn't completely correct:

@ -0,0 +1,33 @@
#include "NamedColor.h"
#include <sstream>
#include <util/StringUtils.h>
std::istream& operator>>(std::istream& str, NamedColor& data) {
std::string line;
NamedColor tmp;
if (std::getline(str, line)) {
std::istringstream iss{line};
if (iss >> tmp.color.red >> tmp.color.blue >> tmp.color.green && std::getline(iss, tmp.name)) {
tmp.name = StringUtils::trim(tmp.name);
/* OK: All read operations worked */
data.swap(tmp); // C++03 as this answer was written a long time ago.
} else {
// One operation failed.
// So set the state on the main stream
// to indicate failure.
str.setstate(std::ios::failbit);
}
}
return str;
}
void NamedColor::swap(NamedColor& other) // C++03 as this answer was written a long time ago.
{
std::swap(color.red, other.color.red);
std::swap(color.green, other.color.green);
std::swap(color.blue, other.color.blue);
std::swap(color.alpha, other.color.alpha);
std::swap(name, other.name);
}

@ -0,0 +1,11 @@
#include <string>
#include <util/Color.h>
struct NamedColor {
std::string name;
ColorU16 color;
friend std::istream& operator>>(std::istream& str, NamedColor& data);
void swap(NamedColor& other);
};
Loading…
Cancel
Save