diff options
| author | Nathan Lee <2431820-nathanal@users.noreply.gitlab.com> | 2019-08-02 07:15:11 +0000 |
|---|---|---|
| committer | Nathan Lee <2431820-nathanal@users.noreply.gitlab.com> | 2019-10-09 23:23:07 +0000 |
| commit | a6c431616c5722b91cfc43b8c93f31ff0a2eecbb (patch) | |
| tree | de77d2384d7363e096c13f1a4a8f9ae9b0e02d06 /src/ui/widget | |
| parent | Backup prefs instead of deleting (diff) | |
| download | inkscape-a6c431616c5722b91cfc43b8c93f31ff0a2eecbb.tar.gz inkscape-a6c431616c5722b91cfc43b8c93f31ff0a2eecbb.zip | |
Change color entry widget UX
- Previous alpha value used in autofill
- Always filter non-hex input
- Autocomplete on enter
- Treat 1-2 digit input as grey colors
- Treat short input (3/4) as shorthand hex notation
- 8 digit hex with # no longer clipped when pasted
- Side effect: filtered input moves cursor forward
https://gitlab.com/inkscape/inkscape/issues/346
Diffstat (limited to 'src/ui/widget')
| -rw-r--r-- | src/ui/widget/color-entry.cpp | 82 | ||||
| -rw-r--r-- | src/ui/widget/color-entry.h | 3 |
2 files changed, 65 insertions, 20 deletions
diff --git a/src/ui/widget/color-entry.cpp b/src/ui/widget/color-entry.cpp index 619a7d515..804350c6b 100644 --- a/src/ui/widget/color-entry.cpp +++ b/src/ui/widget/color-entry.cpp @@ -22,12 +22,17 @@ ColorEntry::ColorEntry(SelectedColor &color) : _color(color) , _updating(false) , _updatingrgba(false) + , _prevpos(0) + , _lastcolor(0) { _color_changed_connection = color.signal_changed.connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged)); _color_dragged_connection = color.signal_dragged.connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged)); + signal_activate().connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged)); + get_buffer()->signal_inserted_text().connect(sigc::mem_fun(this, &ColorEntry::_inputCheck)); _onColorChanged(); - set_max_length(8); + // add extra character for pasting a hash, '#11223344' + set_max_length(9); set_width_chars(8); set_tooltip_text(_("Hexadecimal RGBA value of the color")); } @@ -38,6 +43,13 @@ ColorEntry::~ColorEntry() _color_dragged_connection.disconnect(); } +void ColorEntry::_inputCheck(guint pos, const gchar * /*chars*/, guint n_chars) +{ + // remember position of last character, so we can remove it. + // we only overflow by 1 character at most. + _prevpos = pos + n_chars - 1; +} + void ColorEntry::on_changed() { if (_updating) { @@ -50,33 +62,63 @@ void ColorEntry::on_changed() Glib::ustring text = get_text(); bool changed = false; - // Coerce the value format to eight hex digits - if (!text.empty() && text[0] == '#') { - changed = true; - text.erase(0, 1); - if (text.size() == 6) { - // it was a standard RGB hex - unsigned int alpha = SP_COLOR_F_TO_U(_color.alpha()); - text += Glib::ustring::format(std::hex, std::setw(2), std::setfill(L'0'), alpha); + // Coerce the value format to hexadecimal + for (auto it = text.begin(); it != text.end(); /*++it*/) { + if (!g_ascii_isxdigit(*it)) { + text.erase(it); + changed = true; + } else { + ++it; } } + if (text.size() > 8) { + text.erase(_prevpos, 1); + changed = true; + } + + // autofill rules gchar *str = g_strdup(text.c_str()); gchar *end = nullptr; guint64 rgba = g_ascii_strtoull(str, &end, 16); - if (end != str) { - ptrdiff_t len = end - str; - if (len < 8) { + ptrdiff_t len = end - str; + if (len < 8) { + if (len == 0) { + rgba = _lastcolor; + } else if (len <= 2) { + if (len == 1) { + rgba *= 17; + } + rgba = (rgba << 24) + (rgba << 16) + (rgba << 8); + } else if (len <= 4) { + // display as rrggbbaa + rgba = rgba << (4 * (4 - len)); + guint64 r = rgba & 0xf000; + guint64 g = rgba & 0x0f00; + guint64 b = rgba & 0x00f0; + guint64 a = rgba & 0x000f; + rgba = 17 * ((r << 12) + (g << 8) + (b << 4) + a); + } else { rgba = rgba << (4 * (8 - len)); } - _updatingrgba = true; - if (changed) { - set_text(str); + + if (len == 7) { + rgba = (rgba & 0xfffffff0) + (_lastcolor & 0x00f); + } else if (len == 5) { + rgba = (rgba & 0xfffff000) + (_lastcolor & 0xfff); + } else if (len != 4 && len != 8) { + rgba = (rgba & 0xffffff00) + (_lastcolor & 0x0ff); } - SPColor color(rgba); - _color.setColorAlpha(color, SP_RGBA32_A_F(rgba)); - _updatingrgba = false; } + + _updatingrgba = true; + if (changed) { + set_text(str); + } + SPColor color(rgba); + _color.setColorAlpha(color, SP_RGBA32_A_F(rgba)); + _updatingrgba = false; + g_free(str); } @@ -90,8 +132,8 @@ void ColorEntry::_onColorChanged() SPColor color = _color.color(); gdouble alpha = _color.alpha(); - guint32 rgba = color.toRGBA32(alpha); - Glib::ustring text = Glib::ustring::format(std::hex, std::setw(8), std::setfill(L'0'), rgba); + _lastcolor = color.toRGBA32(alpha); + Glib::ustring text = Glib::ustring::format(std::hex, std::setw(8), std::setfill(L'0'), _lastcolor); Glib::ustring old_text = get_text(); if (old_text != text) { diff --git a/src/ui/widget/color-entry.h b/src/ui/widget/color-entry.h index 883076c7d..4df80def9 100644 --- a/src/ui/widget/color-entry.h +++ b/src/ui/widget/color-entry.h @@ -30,12 +30,15 @@ protected: private: void _onColorChanged(); + void _inputCheck(guint pos, const gchar * /*chars*/, guint /*n_chars*/); SelectedColor &_color; sigc::connection _color_changed_connection; sigc::connection _color_dragged_connection; bool _updating; bool _updatingrgba; + guint32 _lastcolor; + int _prevpos; }; } |
