Skip to content

Commit 86455b4

Browse files
committed
Only operate on SDL clipboard
1 parent aa65232 commit 86455b4

File tree

3 files changed

+84
-73
lines changed

3 files changed

+84
-73
lines changed

src/gui/menu_color.cpp

+34-71
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1717

18-
#include <regex>
19-
#include <sstream>
20-
2118
#include "gui/menu_color.hpp"
2219
#include "menu_item.hpp"
2320
#include "../util/log.hpp"
@@ -38,14 +35,11 @@ ColorMenu::ColorMenu(Color* color_) :
3835
add_color_display(color);
3936

4037
add_hl();
41-
add_entry(MNID_COPY, _("Copy"));
38+
add_entry(MNID_COPY_CLIPBOARD, _("Copy from clipboard"));
4239
if (Color::s_clipboard_color != nullptr)
43-
add_entry(MNID_PASTE, _("Paste"), *Color::s_clipboard_color);
40+
add_entry(MNID_PASTE_CLIPBOARD, _("Paste from clipboard"), *Color::s_clipboard_color);
4441
else
45-
add_entry(MNID_PASTE, _("Paste"), Color(1.f, 1.f, 1.f));
46-
47-
add_hl();
48-
add_entry(MNID_PASTE_CLIPBOARD, _("Paste clipboard"));
42+
add_entry(MNID_PASTE_CLIPBOARD, _("Paste from clipboard"), Color(1.f, 1.f, 1.f));
4943

5044
add_hl();
5145
add_back(_("OK"));
@@ -54,84 +48,53 @@ ColorMenu::ColorMenu(Color* color_) :
5448
void
5549
ColorMenu::menu_action(MenuItem& item)
5650
{
57-
if (item.get_id() == MNID_COPY)
51+
if (item.get_id() == MNID_COPY_CLIPBOARD)
5852
{
5953
if (color)
6054
{
6155
Color::s_clipboard_color = std::make_unique<Color>(*color);
62-
MenuItem& menu_paste_item = get_item_by_id(MNID_PASTE);
56+
MenuItem& menu_paste_item = get_item_by_id(MNID_PASTE_CLIPBOARD);
6357
menu_paste_item.set_text_color(*color);
58+
59+
std::stringstream ss;
60+
ss << "rgb("
61+
<< static_cast<int>(color->red * 255.f) << ","
62+
<< static_cast<int>(color->green * 255.f) << ","
63+
<< static_cast<int>(color->blue * 255.f) << ")";
64+
65+
const std::string clipboard_text = ss.str();
66+
67+
if (SDL_SetClipboardText(clipboard_text.c_str()) != 0)
68+
log_warning << "Failed to set SDL clipboard text: " << SDL_GetError() << std::endl;
6469
}
6570
}
66-
else if (item.get_id() == MNID_PASTE)
67-
{
68-
if (Color::s_clipboard_color)
69-
*color = *Color::s_clipboard_color;
70-
}
7171
else if (item.get_id() == MNID_PASTE_CLIPBOARD)
7272
{
73-
if (!SDL_HasClipboardText())
74-
return;
75-
76-
const char* clipboard_text = SDL_GetClipboardText();
77-
if (!clipboard_text)
78-
return;
79-
80-
const std::string text(clipboard_text);
81-
SDL_free(const_cast<char*>(clipboard_text));
82-
83-
Color new_color;
84-
bool is_valid_format = false;
85-
86-
// rgb(r,g,b)
87-
const std::regex rgb_format(R"(^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$)");
88-
std::smatch rgb_matches;
89-
90-
if (std::regex_match(text, rgb_matches, rgb_format))
73+
if (SDL_HasClipboardText())
9174
{
92-
const int r = std::stoi(rgb_matches[1].str());
93-
const int g = std::stoi(rgb_matches[2].str());
94-
const int b = std::stoi(rgb_matches[3].str());
75+
const char* clipboard_text = SDL_GetClipboardText();
76+
if (!clipboard_text)
77+
return;
9578

96-
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255)
97-
{
98-
new_color = Color(static_cast<float>(r) / 255.0f, static_cast<float>(g) / 255.0f, static_cast<float>(b) / 255.0f, 1.0f);
99-
is_valid_format = true;
100-
}
101-
}
102-
else
103-
{
104-
// #rrggbb
105-
const std::regex hex_format(R"(^\s*#([A-Fa-f0-9]{6})\s*$)");
106-
std::smatch hex_matches;
79+
const std::string text(clipboard_text);
80+
SDL_free(const_cast<char*>(clipboard_text));
10781

108-
if (std::regex_match(text, hex_matches, hex_format))
109-
{
110-
const std::string hex_value = hex_matches[1].str();
111-
unsigned int hex_color;
112-
std::stringstream ss;
113-
ss << std::hex << hex_value;
114-
ss >> hex_color;
82+
std::optional<Color> new_color;
83+
new_color = Color::from_rgb_string(text);
11584

116-
const float r = ((hex_color >> 16) & 0xFF) / 255.0f;
117-
const float g = ((hex_color >> 8) & 0xFF) / 255.0f;
118-
const float b = (hex_color & 0xFF) / 255.0f;
85+
if (!new_color)
86+
new_color = Color::from_hex_string(text);
11987

120-
new_color = Color(r, g, b, 1.0f);
121-
is_valid_format = true;
88+
if (new_color)
89+
{
90+
*color = *new_color;
91+
Color::s_clipboard_color = std::make_unique<Color>(*new_color);
92+
MenuItem& menu_paste_item = get_item_by_id(MNID_PASTE_CLIPBOARD);
93+
menu_paste_item.set_text_color(*new_color);
12294
}
95+
else
96+
log_warning << "Invalid color format: " << text << ". Supported formats: rgb(r,g,b) and #rrggbb" << std::endl;
12397
}
124-
125-
if (is_valid_format)
126-
{
127-
*color = new_color;
128-
129-
Color::s_clipboard_color = std::make_unique<Color>(new_color);
130-
MenuItem& menu_paste_item = get_item_by_id(MNID_PASTE);
131-
menu_paste_item.set_text_color(new_color);
132-
}
133-
else
134-
log_warning << "Invalid color format: " << text << ". Supported formats: rgb(r,g,b) and #rrggbb" << std::endl;
13598
}
13699
}
137100

src/gui/menu_color.hpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ class ColorMenu final : public Menu
3636
private:
3737
enum MenuIDs
3838
{
39-
MNID_COPY = 1,
40-
MNID_PASTE,
39+
MNID_COPY_CLIPBOARD = 1,
4140
MNID_PASTE_CLIPBOARD
4241
};
4342
};

src/video/color.hpp

+49
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@
1717
#ifndef HEADER_SUPERTUX_VIDEO_COLOR_HPP
1818
#define HEADER_SUPERTUX_VIDEO_COLOR_HPP
1919

20+
#include "../math/util.hpp"
21+
2022
#include <string>
23+
#include <sstream>
2124
#include <vector>
2225
#include <math.h>
2326
#include <memory>
27+
#include <optional>
28+
#include <regex>
2429

2530
#include <SDL_image.h>
2631

@@ -84,6 +89,50 @@ class Color final
8489
static_cast<float>(a) / 255.0f);
8590
}
8691

92+
static std::optional<Color> from_rgb_string(const std::string& rgb_string)
93+
{
94+
const std::regex rgb_format(R"(^\s*rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$)");
95+
std::smatch matches;
96+
97+
if (std::regex_match(rgb_string, matches, rgb_format))
98+
{
99+
const int r = std::stoi(matches[1].str());
100+
const int g = std::stoi(matches[2].str());
101+
const int b = std::stoi(matches[3].str());
102+
103+
if (math::in_bounds(r, 0, 255) && math::in_bounds(g, 0, 255) && math::in_bounds(b, 0, 255))
104+
{
105+
return Color(static_cast<float>(r) / 255.0f,
106+
static_cast<float>(g) / 255.0f,
107+
static_cast<float>(b) / 255.0f,
108+
1.0f);
109+
}
110+
}
111+
return std::nullopt;
112+
}
113+
114+
static std::optional<Color> from_hex_string(const std::string& hex_string)
115+
{
116+
const std::regex hex_format(R"(^\s*#([A-Fa-f0-9]{6})\s*$)");
117+
std::smatch matches;
118+
119+
if (std::regex_match(hex_string, matches, hex_format))
120+
{
121+
const std::string hex_value = matches[1].str();
122+
unsigned int hex_color;
123+
std::stringstream ss;
124+
ss << std::hex << hex_value;
125+
ss >> hex_color;
126+
127+
const float r = ((hex_color >> 16) & 0xFF) / 255.0f;
128+
const float g = ((hex_color >> 8) & 0xFF) / 255.0f;
129+
const float b = (hex_color & 0xFF) / 255.0f;
130+
131+
return Color(r, g, b, 1.0f);
132+
}
133+
return std::nullopt;
134+
}
135+
87136
static Color from_linear(float r, float g, float b, float a = 1.0f)
88137
{
89138
return Color(add_gamma(r), add_gamma(g), add_gamma(b), a);

0 commit comments

Comments
 (0)