From 7f93aadff453ef0da1cc2bd0ca70703a7aaf99d0 Mon Sep 17 00:00:00 2001 From: bruhmoent Date: Sun, 17 Nov 2024 02:12:30 +0100 Subject: [PATCH] Implement pasting color values from the SDL's clipboard --- src/gui/item_action.cpp | 10 +++-- src/gui/item_action.hpp | 2 +- src/gui/menu.cpp | 12 ++++++ src/gui/menu.hpp | 2 + src/gui/menu_color.cpp | 83 ++++++++++++++++++++++++++++++++++++++--- src/gui/menu_color.hpp | 3 +- 6 files changed, 101 insertions(+), 11 deletions(-) diff --git a/src/gui/item_action.cpp b/src/gui/item_action.cpp index 7c250635885..9c07333ce4b 100644 --- a/src/gui/item_action.cpp +++ b/src/gui/item_action.cpp @@ -16,8 +16,8 @@ #include "gui/item_action.hpp" -ItemAction::ItemAction(const std::string& text, int id, std::function callback) : - MenuItem(text, id), +ItemAction::ItemAction(const std::string& text, int id, std::function callback, const Color& text_color) : + MenuItem(text, id, text_color), m_callback(std::move(callback)) { } @@ -25,8 +25,10 @@ ItemAction::ItemAction(const std::string& text, int id, std::function ca void ItemAction::process_action(const MenuAction& action) { - if (action == MenuAction::HIT) { - if (m_callback) { + if (action == MenuAction::HIT) + { + if (m_callback) + { m_callback(); } } diff --git a/src/gui/item_action.hpp b/src/gui/item_action.hpp index c166fde5137..e9a7170fc6d 100644 --- a/src/gui/item_action.hpp +++ b/src/gui/item_action.hpp @@ -22,7 +22,7 @@ class ItemAction final : public MenuItem { public: - ItemAction(const std::string& text, int id = -1, std::function callback = {}); + ItemAction(const std::string& text, int id = -1, std::function callback = {}, const Color& text_color = Color(1.f, 1.f, 1.f)); virtual void process_action(const MenuAction& action) override; diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp index fc4486925ac..e5894c088fd 100644 --- a/src/gui/menu.cpp +++ b/src/gui/menu.cpp @@ -204,6 +204,18 @@ Menu::add_entry(const std::string& text, const std::function& callback) return add_item(text, -1, callback); } +ItemAction& +Menu::add_entry(int id, const std::string& text, const Color& text_color) +{ + return add_item(text, id, [](){}, text_color); +} + +ItemAction& +Menu::add_entry(const std::string& text, const std::function& callback, const Color& text_color) +{ + return add_item(text, -1, callback, text_color); +} + ItemInactive& Menu::add_inactive(const std::string& text, bool default_color) { diff --git a/src/gui/menu.hpp b/src/gui/menu.hpp index 59362245315..d1eb6ff04e4 100644 --- a/src/gui/menu.hpp +++ b/src/gui/menu.hpp @@ -77,7 +77,9 @@ class Menu ItemHorizontalLine& add_hl(); ItemLabel& add_label(const std::string& text); ItemAction& add_entry(int id, const std::string& text); + ItemAction& add_entry(int id, const std::string& text, const Color& text_color); ItemAction& add_entry(const std::string& text, const std::function& callback); + ItemAction& add_entry(const std::string& text, const std::function& callback, const Color& text_color); ItemToggle& add_toggle(int id, const std::string& text, bool* toggled, bool center_text = false); ItemToggle& add_toggle(int id, const std::string& text, const std::function& get_func, diff --git a/src/gui/menu_color.cpp b/src/gui/menu_color.cpp index 62dda19da57..7a75a87c846 100644 --- a/src/gui/menu_color.cpp +++ b/src/gui/menu_color.cpp @@ -1,5 +1,6 @@ // SuperTux // Copyright (C) 2015 Hume2 +// 2024 bruhmoent // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -14,8 +15,12 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +#include +#include + #include "gui/menu_color.hpp" #include "menu_item.hpp" +#include "../util/log.hpp" #include "util/gettext.hpp" @@ -33,11 +38,14 @@ ColorMenu::ColorMenu(Color* color_) : add_color_display(color); add_hl(); - add_item(std::make_unique(_("Copy"), MNID_COPY)); - add_item(std::make_unique( - _("Paste"), - MNID_PASTE, - Color::s_clipboard_color ? std::make_optional(*Color::s_clipboard_color) : std::nullopt)); + add_entry(MNID_COPY, _("Copy")); + if (Color::s_clipboard_color != nullptr) + add_entry(MNID_PASTE, _("Paste"), *Color::s_clipboard_color); + else + add_entry(MNID_PASTE, _("Paste"), Color(1.f, 1.f, 1.f)); + + add_hl(); + add_entry(MNID_PASTE_CLIPBOARD, _("Paste clipboard")); add_hl(); add_back(_("OK")); @@ -60,6 +68,71 @@ ColorMenu::menu_action(MenuItem& item) if (Color::s_clipboard_color) *color = *Color::s_clipboard_color; } + else if (item.get_id() == MNID_PASTE_CLIPBOARD) + { + if (!SDL_HasClipboardText()) + return; + + const char* clipboard_text = SDL_GetClipboardText(); + if (!clipboard_text) + return; + + const std::string text(clipboard_text); + SDL_free((void*)clipboard_text); + + Color new_color; + bool is_valid_format = false; + + // rgb(r,g,b) + const std::regex rgb_format(R"(^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$)"); + std::smatch rgb_matches; + + if (std::regex_match(text, rgb_matches, rgb_format)) + { + const int r = std::stoi(rgb_matches[1].str()); + const int g = std::stoi(rgb_matches[2].str()); + const int b = std::stoi(rgb_matches[3].str()); + + if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) + { + new_color = Color(r/255.0f, g/255.0f, b/255.0f, 1.0f); + is_valid_format = true; + } + } + else + { + // #rrggbb + const std::regex hex_format(R"(^\s*#([A-Fa-f0-9]{6})\s*$)"); + std::smatch hex_matches; + + if (std::regex_match(text, hex_matches, hex_format)) + { + const std::string hex_value = hex_matches[1].str(); + unsigned int hex_color; + std::stringstream ss; + ss << std::hex << hex_value; + ss >> hex_color; + + const float r = ((hex_color >> 16) & 0xFF)/255.0f; + const float g = ((hex_color >> 8) & 0xFF)/255.0f; + const float b = (hex_color & 0xFF)/255.0f; + + new_color = Color(r, g, b, 1.0f); + is_valid_format = true; + } + } + + if (is_valid_format) + { + *color = new_color; + + Color::s_clipboard_color = std::make_unique(new_color); + MenuItem& menu_paste_item = get_item_by_id(MNID_PASTE); + menu_paste_item.set_text_color(new_color); + } + else + log_warning << "Invalid color format: " << text << ". Supported formats: rgb(r,g,b) and #rrggbb" << std::endl; + } } /* EOF */ diff --git a/src/gui/menu_color.hpp b/src/gui/menu_color.hpp index 3e5c516c4eb..1870757bf58 100644 --- a/src/gui/menu_color.hpp +++ b/src/gui/menu_color.hpp @@ -37,7 +37,8 @@ class ColorMenu final : public Menu enum MenuIDs { MNID_COPY = 1, - MNID_PASTE + MNID_PASTE, + MNID_PASTE_CLIPBOARD }; };