diff --git a/CMakeLists.txt b/CMakeLists.txt index 78bb75f9..97cbb042 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/src/config-dev.h.in b/src/config-dev.h.in index 8ec9f158..ba625839 100644 --- a/src/config-dev.h.in +++ b/src/config-dev.h.in @@ -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 diff --git a/src/control/Control.h b/src/control/Control.h index 9daac4f9..e63b6027 100644 --- a/src/control/Control.h +++ b/src/control/Control.h @@ -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; diff --git a/src/control/XournalMain.cpp b/src/control/XournalMain.cpp index 53679a43..e524d5dd 100644 --- a/src/control/XournalMain.cpp +++ b/src/control/XournalMain.cpp @@ -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; } diff --git a/src/control/settings/Settings.cpp b/src/control/settings/Settings.cpp index 0f0918b4..1451d9bc 100644 --- a/src/control/settings/Settings.cpp +++ b/src/control/settings/Settings.cpp @@ -2,6 +2,8 @@ #include +#include + #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; } diff --git a/src/control/settings/Settings.h b/src/control/settings/Settings.h index d23d2dc0..6918eb26 100644 --- a/src/control/settings/Settings.h +++ b/src/control/settings/Settings.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -895,4 +896,8 @@ private: * e.g. "en_US" */ std::string preferredLocale; + +public: + Palette* palette; + fs::path paletteFilePath; }; diff --git a/src/gui/dialog/toolbarCustomize/CustomizeableColorList.cpp b/src/gui/dialog/toolbarCustomize/CustomizeableColorList.cpp deleted file mode 100644 index af279e43..00000000 --- a/src/gui/dialog/toolbarCustomize/CustomizeableColorList.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "CustomizeableColorList.h" - -#include - -#include - -#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* { return &this->colors; } - -void CustomizeableColorList::addPredefinedColor(Color color, string name) { - this->colors.push_back(new XojColor(color, std::move(name))); -} diff --git a/src/gui/dialog/toolbarCustomize/CustomizeableColorList.h b/src/gui/dialog/toolbarCustomize/CustomizeableColorList.h deleted file mode 100644 index c6d9df1d..00000000 --- a/src/gui/dialog/toolbarCustomize/CustomizeableColorList.h +++ /dev/null @@ -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 -#include - -#include "gui/XojColor.h" - -#include "XournalType.h" - -class CustomizeableColorList { -public: - CustomizeableColorList(); - virtual ~CustomizeableColorList(); - -public: - vector* getPredefinedColors(); - -private: - void addPredefinedColor(Color color, string name); - -private: - vector colors; -}; diff --git a/src/gui/dialog/toolbarCustomize/ToolbarAdapter.cpp b/src/gui/dialog/toolbarCustomize/ToolbarAdapter.cpp index 34a68f42..1a88b676 100644 --- a/src/gui/dialog/toolbarCustomize/ToolbarAdapter.cpp +++ b/src/gui/dialog/toolbarCustomize/ToolbarAdapter.cpp @@ -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); diff --git a/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.cpp b/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.cpp index 4024596c..084664ac 100644 --- a/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.cpp +++ b/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.cpp @@ -2,15 +2,17 @@ #include +#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)); } diff --git a/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.h b/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.h index c7c1de7d..4c216e39 100644 --- a/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.h +++ b/src/gui/dialog/toolbarCustomize/ToolbarCustomizeDialog.h @@ -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 itemDatalist; MainWindow* win; diff --git a/src/gui/toolbarMenubar/ColorToolItem.cpp b/src/gui/toolbarMenubar/ColorToolItem.cpp index be6ea59c..d7c82abb 100644 --- a/src/gui/toolbarMenubar/ColorToolItem.cpp +++ b/src/gui/toolbarMenubar/ColorToolItem.cpp @@ -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; diff --git a/src/gui/toolbarMenubar/ColorToolItem.h b/src/gui/toolbarMenubar/ColorToolItem.h index 0cfce063..8a725aad 100644 --- a/src/gui/toolbarMenubar/ColorToolItem.h +++ b/src/gui/toolbarMenubar/ColorToolItem.h @@ -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(); /** diff --git a/src/gui/toolbarMenubar/ToolMenuHandler.cpp b/src/gui/toolbarMenubar/ToolMenuHandler.cpp index 444b6ea3..bc5d3d16 100644 --- a/src/gui/toolbarMenubar/ToolMenuHandler.cpp +++ b/src/gui/toolbarMenubar/ToolMenuHandler.cpp @@ -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(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) { diff --git a/src/gui/toolbarMenubar/ToolMenuHandler.h b/src/gui/toolbarMenubar/ToolMenuHandler.h index 8eee0cdd..c6363fd6 100644 --- a/src/gui/toolbarMenubar/ToolMenuHandler.h +++ b/src/gui/toolbarMenubar/ToolMenuHandler.h @@ -69,6 +69,8 @@ public: vector* getToolItems(); + Control* getControl(); + bool isColorInUse(Color color); void disableAudioPlaybackButtons(); diff --git a/src/gui/toolbarMenubar/model/ColorPalette.cpp b/src/gui/toolbarMenubar/model/ColorPalette.cpp new file mode 100644 index 00000000..a987b448 --- /dev/null +++ b/src/gui/toolbarMenubar/model/ColorPalette.cpp @@ -0,0 +1,132 @@ +#include "ColorPalette.h" + +#include +#include +#include + +#include +#include + +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 diff --git a/src/gui/toolbarMenubar/model/ColorPalette.h b/src/gui/toolbarMenubar/model/ColorPalette.h new file mode 100644 index 00000000..6bac7918 --- /dev/null +++ b/src/gui/toolbarMenubar/model/ColorPalette.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +#include +#include + +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 header; + std::vector colors; + + Palette(fs::path path); + + NamedColor getNext(int inc = 1); + void load(); + void reset(); + + static void create_default(fs::path path); +}; \ No newline at end of file diff --git a/src/gui/toolbarMenubar/model/ToolbarColorNames.cpp b/src/gui/toolbarMenubar/model/ToolbarColorNames.cpp deleted file mode 100644 index 7476b3cc..00000000 --- a/src/gui/toolbarMenubar/model/ToolbarColorNames.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include "ToolbarColorNames.h" - -#include - -#include - -#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); -} diff --git a/src/gui/toolbarMenubar/model/ToolbarColorNames.h b/src/gui/toolbarMenubar/model/ToolbarColorNames.h deleted file mode 100644 index 7eef907b..00000000 --- a/src/gui/toolbarMenubar/model/ToolbarColorNames.h +++ /dev/null @@ -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 -#include - -#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 predefinedColorNames{}; -}; diff --git a/src/util/Color.h b/src/util/Color.h index 4d6b9e1a..2f3d3443 100644 --- a/src/util/Color.h +++ b/src/util/Color.h @@ -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: diff --git a/src/util/NamedColor.cpp b/src/util/NamedColor.cpp new file mode 100644 index 00000000..0feb24fe --- /dev/null +++ b/src/util/NamedColor.cpp @@ -0,0 +1,33 @@ +#include "NamedColor.h" + +#include + +#include + +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); +} \ No newline at end of file diff --git a/src/util/NamedColor.h b/src/util/NamedColor.h new file mode 100644 index 00000000..68ab087c --- /dev/null +++ b/src/util/NamedColor.h @@ -0,0 +1,11 @@ +#include + +#include + +struct NamedColor { + std::string name; + ColorU16 color; + + friend std::istream& operator>>(std::istream& str, NamedColor& data); + void swap(NamedColor& other); +}; \ No newline at end of file