diff --git a/src/ui/widget/color-entry.cpp b/src/ui/widget/color-entry.cpp index 3b519cc9b35769be0f8bb113b71cc5a6377c1102..e214c865ecf8798f4a2e01a93589e4fb4b33b5ef 100644 --- a/src/ui/widget/color-entry.cpp +++ b/src/ui/widget/color-entry.cpp @@ -57,7 +57,14 @@ void ColorEntry::on_changed() return; } - auto new_color = Colors::Color::parse(get_text()); + auto text = get_text(); + // If it looks like a plain hex string (e.g., "ff00ff") add a '#' + // so both "ff00ff" and "#ff00ff" are accepted. + if (looksLikeHex(text)) { + text = "#" + text; + } + + auto new_color = Colors::Color::parse(text); _updatingrgba = true; if (new_color) { @@ -109,6 +116,26 @@ void ColorEntry::_onColorChanged() } } +// Checks if a text looks like a hex color code +// for example, returns true for "fff" or "ff00ff", +// but false for actual hex codes (like "#fff" or "#ff00ff") +// or any invalid hex strings. +bool ColorEntry::looksLikeHex(const Glib::ustring &text) const +{ + if (text.empty() || text[0] == '#') { + return false; + } + + auto len = text.size(); + if (len != 3 && len != 4 && len != 6 && len != 8) { + return false; + } + + return std::all_of(text.begin(), text.end(), [](unsigned char c) { + return std::isxdigit(c); + }); +} + } // namespace /* diff --git a/src/ui/widget/color-entry.h b/src/ui/widget/color-entry.h index 9dbb82e9ddaebd14fc9a4b1c49f4555e65fd477f..72afbb2fef8638bb20ec324f57b9c907caceff06 100644 --- a/src/ui/widget/color-entry.h +++ b/src/ui/widget/color-entry.h @@ -32,6 +32,7 @@ protected: private: void _onColorChanged(); void _inputCheck(guint pos, const gchar * /*chars*/, guint /*n_chars*/); + bool looksLikeHex(const Glib::ustring &text) const; std::shared_ptr _colors; bool _updating;