summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNathan Lee <2431820-nathanal@users.noreply.gitlab.com>2019-08-02 07:15:11 +0000
committerNathan Lee <2431820-nathanal@users.noreply.gitlab.com>2019-10-09 23:23:07 +0000
commita6c431616c5722b91cfc43b8c93f31ff0a2eecbb (patch)
treede77d2384d7363e096c13f1a4a8f9ae9b0e02d06 /src
parentBackup prefs instead of deleting (diff)
downloadinkscape-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')
-rw-r--r--src/ui/widget/color-entry.cpp82
-rw-r--r--src/ui/widget/color-entry.h3
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;
};
}