[gnome-builder] color picker: add a color picker plugin



commit c0bfcb9c7b0bb50ca9318cd57bde79d0e30d2d64
Author: Sebastien Lafargue <slafargue gnome org>
Date:   Wed Jul 13 21:34:53 2016 +0200

    color picker: add a color picker plugin
    
    A color-picker panel, activated by the view contextual menu.
    
    In addition, color strings are colored in the activated view.
    Cursor movements and color panel react together.

 configure.ac                                       |    2 +
 plugins/Makefile.am                                |    1 +
 plugins/color-picker/Makefile.am                   |   66 ++
 plugins/color-picker/TODO.md                       |   47 ++
 plugins/color-picker/color-picker.plugin           |    8 +
 plugins/color-picker/configure.ac                  |   12 +
 plugins/color-picker/data/basic.xml                |   32 +
 plugins/color-picker/data/svg.gpl                  |  142 +++++
 .../gb-color-picker-document-monitor.c             |  575 ++++++++++++++++++
 .../gb-color-picker-document-monitor.h             |   50 ++
 plugins/color-picker/gb-color-picker-helper.c      |  293 +++++++++
 plugins/color-picker/gb-color-picker-helper.h      |   53 ++
 plugins/color-picker/gb-color-picker-plugin.c      |   30 +
 plugins/color-picker/gb-color-picker-prefs-list.c  |   63 ++
 plugins/color-picker/gb-color-picker-prefs-list.h  |   36 ++
 .../gb-color-picker-prefs-palette-list.c           |  210 +++++++
 .../gb-color-picker-prefs-palette-list.h           |   37 ++
 .../gb-color-picker-prefs-palette-row.c            |  486 +++++++++++++++
 .../gb-color-picker-prefs-palette-row.h            |   36 ++
 plugins/color-picker/gb-color-picker-prefs.c       |  635 ++++++++++++++++++++
 plugins/color-picker/gb-color-picker-prefs.h       |   44 ++
 plugins/color-picker/gb-color-picker-private.h     |   31 +
 .../color-picker/gb-color-picker-workbench-addin.c |  533 ++++++++++++++++
 .../color-picker/gb-color-picker-workbench-addin.h |   32 +
 plugins/color-picker/gb-color-picker.gresource.xml |   23 +
 ...builder.plugins.color_picker_plugin.gschema.xml |   44 ++
 .../color-picker/gtk/color-picker-palette-row.ui   |   62 ++
 .../gtk/color-picker-prefs-palette-list.ui         |   36 ++
 plugins/color-picker/gtk/color-picker-prefs.ui     |  635 ++++++++++++++++++++
 plugins/color-picker/gtk/color-picker-preview.ui   |   67 ++
 plugins/color-picker/gtk/color-picker.ui           |   71 +++
 plugins/color-picker/gtk/menus.ui                  |   12 +
 plugins/color-picker/icons/assets.svg              |  535 +++++++++++++++++
 plugins/color-picker/icons/assets.txt              |    2 +
 .../color-picker/icons/palette/load-palette.svg    |   30 +
 .../color-picker/icons/palette/save-palette.svg    |   29 +
 plugins/color-picker/icons/render-assets.py        |   50 ++
 plugins/color-picker/icons/render-assets.rb        |   79 +++
 .../color-picker/icons/viewmode/viewmode-list.svg  |   31 +
 .../icons/viewmode/viewmode-swatchs.svg            |   43 ++
 plugins/color-picker/theme/Adwaita-dark.css        |    8 +
 plugins/color-picker/theme/Adwaita-shared.css      |  326 ++++++++++
 plugins/color-picker/theme/Adwaita.css             |   10 +
 po/POTFILES.in                                     |    7 +
 44 files changed, 5554 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 94b4e56..62a6064 100644
--- a/configure.ac
+++ b/configure.ac
@@ -282,6 +282,7 @@ m4_include([plugins/autotools-templates/configure.ac])
 m4_include([plugins/build-tools/configure.ac])
 m4_include([plugins/c-pack/configure.ac])
 m4_include([plugins/clang/configure.ac])
+m4_include([plugins/color-picker/configure.ac])
 m4_include([plugins/command-bar/configure.ac])
 m4_include([plugins/comment-code/configure.ac])
 m4_include([plugins/contributing/configure.ac])
@@ -580,6 +581,7 @@ echo "  Autotools ............................ : ${enable_autotools_plugin}"
 echo "  Build Tools .......................... : ${enable_build_tools_plugin}"
 echo "  C Language Pack ...................... : ${enable_c_pack_plugin}"
 echo "  Clang ................................ : ${enable_clang_plugin}"
+echo "  Color picker.......................... : ${enable_color_picker_plugin}"
 echo "  Command Bar .......................... : ${enable_command_bar_plugin}"
 echo "  Comment Code.......................... : ${enable_comment_code_plugin}"
 echo "  Contribute ........................... : ${enable_contributing_plugin}"
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index d1617c8..0827d68 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -4,6 +4,7 @@ SUBDIRS = \
        build-tools \
        c-pack \
        clang \
+       color-picker \
        command-bar \
        comment-code \
        contributing \
diff --git a/plugins/color-picker/Makefile.am b/plugins/color-picker/Makefile.am
new file mode 100644
index 0000000..d4de2bb
--- /dev/null
+++ b/plugins/color-picker/Makefile.am
@@ -0,0 +1,66 @@
+if ENABLE_COLOR_PICKER_PLUGIN
+
+CLEANFILES =
+DISTCLEANFILES =
+BUILT_SOURCES =
+EXTRA_DIST = $(plugin_DATA)
+
+plugindir = $(libdir)/gnome-builder/plugins
+plugin_LTLIBRARIES = libcolor-picker-plugin.la
+dist_plugin_DATA = color-picker.plugin
+
+libcolor_picker_plugin_la_SOURCES =          \
+       gb-color-picker-helper.c             \
+       gb-color-picker-helper.h             \
+       gb-color-picker-plugin.c             \
+       gb-color-picker-document-monitor.c   \
+       gb-color-picker-document-monitor.h   \
+       gb-color-picker-prefs.c              \
+       gb-color-picker-prefs.h              \
+       gb-color-picker-prefs-list.c         \
+       gb-color-picker-prefs-palette-list.h \
+       gb-color-picker-prefs-palette-list.c \
+       gb-color-picker-prefs-list.h         \
+       gb-color-picker-prefs-palette-row.c  \
+       gb-color-picker-prefs-palette-row.h  \
+       gb-color-picker-private.h            \
+       gb-color-picker-workbench-addin.c    \
+       gb-color-picker-workbench-addin.h    \
+       $(NULL)
+
+libcolor_picker_plugin_la_includes =   \
+       -I$(top_srcdir)/contrib/gstyle \
+       $(NULL)
+
+nodist_libcolor_picker_plugin_la_SOURCES = \
+       gb-color-picker-resources.c        \
+       gb-color-picker-resources.h        \
+       $(NULL)
+
+libcolor_picker_plugin_la_CFLAGS = $(PLUGIN_CFLAGS) $(GSTYLE_CFLAGS)
+libcolor_picker_plugin_la_LIBADD = \
+       $(GSTYLE_LIBS) \
+       $(top_builddir)/contrib/gstyle/libgstyle-private.la \
+       $(NULL)
+
+libcolor_picker_plugin_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+
+glib_resources_c = gb-color-picker-resources.c
+glib_resources_h = gb-color-picker-resources.h
+glib_resources_xml = gb-color-picker.gresource.xml
+glib_resources_namespace = gb_color_picker
+include $(top_srcdir)/build/autotools/Makefile.am.gresources
+
+include $(top_srcdir)/plugins/Makefile.plugin
+
+gsettings_SCHEMAS =                                                         \
+       gsettings/org.gnome.builder.plugins.color_picker_plugin.gschema.xml \
+       $(NULL)
+
+.PRECIOUS: $(gsettings_SCHEMAS)
+
+@GSETTINGS_RULES@
+
+endif
+
+-include $(top_srcdir)/git.mk
diff --git a/plugins/color-picker/TODO.md b/plugins/color-picker/TODO.md
new file mode 100644
index 0000000..2464e20
--- /dev/null
+++ b/plugins/color-picker/TODO.md
@@ -0,0 +1,47 @@
+#TODO list:
+
+## Enhancements :
+
+### Palettes :
+- use need attention symbol in changed palettes.
+- edit colorwidget names in palettes
+- show ID and number of colors (tooltip ?)
+
+### Save and load palettes dialogs :
+- load more than one palette at once.
+- add button the choose the save format
+
+### Panel :
+- show complex colors and nested ones: see css parser functions handling.
+- How to close it ?
+- activated globaly (but nedd a color sub-menu) or per view like now ?
+- filter prefs page ?
+
+### Color Strings :
+- add a way to choose a reference format to insert in the view ( label as a radio ? ).
+
+### search list :
+- re-sort the list starting by the searched prefix.
+- add palettes and current file colors to the list:
+  an UI could be toggle buttons at the search list top.
+
+### Prefs :
+- separate color components and color strings unit choices.
+
+### Assets :
+- fix python script (till now, the rubby one is used).
+- percent and degree icons are fuzzy.
+
+## FIXES :
+
+### Prefs :
+- checked palette row with long name make the panel ask more width:
+  partialy fixed, but hard problem :
+    if you select a row with a row name larger than the previously selected and
+    the panel has small width, it make the panel grow and shrink when changing rows.
+
+- add some scrolledwindow to the pages :
+  done for the palette list but there's a size problem somewhere since
+  the addition of max-content-* to GtkScrolledWindow.
+
+- focus paths.
diff --git a/plugins/color-picker/color-picker.plugin b/plugins/color-picker/color-picker.plugin
new file mode 100644
index 0000000..9efb9fd
--- /dev/null
+++ b/plugins/color-picker/color-picker.plugin
@@ -0,0 +1,8 @@
+[Plugin]
+Module=color-picker-plugin
+Name=Color Picker
+Description=Show a color picker to inspect or change text color codes
+Authors=Sébastien Lafargue <slafargue gnome org>
+Copyright=Copyright © 2016 Sébastien Lafargue
+Depends=editor
+Builtin=true
diff --git a/plugins/color-picker/configure.ac b/plugins/color-picker/configure.ac
new file mode 100644
index 0000000..57652ec
--- /dev/null
+++ b/plugins/color-picker/configure.ac
@@ -0,0 +1,12 @@
+# --enable-color-picker-plugin=yes/no
+AC_ARG_ENABLE([color-picker-plugin],
+              [AS_HELP_STRING([--enable-color-picker-plugin=@<:@yes/no@:>@],
+                              [Build with support for Showing a color picker on color codes.])],
+              [enable_color_picker_plugin=$enableval],
+              [enable_color_picker_plugin=yes])
+
+# for if ENABLE_COLOR_PICKER1_PLUGIN in Makefile.am
+AM_CONDITIONAL(ENABLE_COLOR_PICKER_PLUGIN, test x$enable_color_picker_plugin != xno)
+
+# Ensure our makefile is generated by autoconf
+AC_CONFIG_FILES([plugins/color-picker/Makefile])
diff --git a/plugins/color-picker/data/basic.xml b/plugins/color-picker/data/basic.xml
new file mode 100644
index 0000000..f62c42d
--- /dev/null
+++ b/plugins/color-picker/data/basic.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+
+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
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<palette id="basic" _name="Basic">
+
+  <color name="color_hex6"           value="#808080"/>
+  <color name="color_hex3"           value="#1aF"/>
+  <color name="color_rgb"            value="rgb(100, 200, 50)"/>
+  <color name="color_rgb_percent"    value="rgb(10%, 50%, 70%)"/>
+  <color name="color_rgba"           value="rgba(0, 10, 70, 1)"/>
+  <color name="color_rgba_percent"   value="rgba(10%, 50%, 40%, 0.5)"/>
+  <color name="color_hsl"            value="hsl(100, 100%, 50%)"/>
+  <color name="color_hsla"           value="hsla(400, 50%, 40%, 0.5)"/>
+  <color name="color_named"          value="aliceblue"/>
+
+</palette>
diff --git a/plugins/color-picker/data/svg.gpl b/plugins/color-picker/data/svg.gpl
new file mode 100644
index 0000000..d8b868b
--- /dev/null
+++ b/plugins/color-picker/data/svg.gpl
@@ -0,0 +1,142 @@
+GIMP Palette
+Name: SVG
+#
+  0   0   0    black (#000000)
+105 105 105    dimgray (#696969)
+128 128 128    gray (#808080)
+169 169 169    darkgray (#A9A9A9)
+192 192 192    silver (#C0C0C0)
+211 211 211    lightgray (#D3D3D3)
+220 220 220    gainsboro (#DCDCDC)
+245 245 245    whitesmoke (#F5F5F5)
+255 255 255    white (#FFFFFF)
+188 143 143    rosybrown (#BC8F8F)
+205  92  92    indianred (#CD5C5C)
+165  42  42    brown (#A52A2A)
+178  34  34    firebrick (#B22222)
+240 128 128    lightcoral (#F08080)
+128   0   0    maroon (#800000)
+139   0   0    darkred (#8B0000)
+255   0   0    red (#FF0000)
+255 250 250    snow (#FFFAFA)
+255 228 225    mistyrose (#FFE4E1)
+250 128 114    salmon (#FA8072)
+255  99  71    tomato (#FF6347)
+233 150 122    darksalmon (#E9967A)
+255 127  80    coral (#FF7F50)
+255  69   0    orangered (#FF4500)
+255 160 122    lightsalmon (#FFA07A)
+160  82  45    sienna (#A0522D)
+255 245 238    seashell (#FFF5EE)
+210 105  30    chocolate (#D2691E)
+139  69  19    saddlebrown (#8B4513)
+244 164  96    sandybrown (#F4A460)
+255 218 185    peachpuff (#FFDAB9)
+205 133  63    peru (#CD853F)
+250 240 230    linen (#FAF0E6)
+255 228 196    bisque (#FFE4C4)
+255 140   0    darkorange (#FF8C00)
+222 184 135    burlywood (#DEB887)
+210 180 140    tan (#D2B48C)
+250 235 215    antiquewhite (#FAEBD7)
+255 222 173    navajowhite (#FFDEAD)
+255 235 205    blanchedalmond (#FFEBCD)
+255 239 213    papayawhip (#FFEFD5)
+255 228 181    moccasin (#FFE4B5)
+255 165   0    orange (#FFA500)
+245 222 179    wheat (#F5DEB3)
+253 245 230    oldlace (#FDF5E6)
+255 250 240    floralwhite (#FFFAF0)
+184 134  11    darkgoldenrod (#B8860B)
+218 165  32    goldenrod (#DAA520)
+255 248 220    cornsilk (#FFF8DC)
+255 215   0    gold (#FFD700)
+240 230 140    khaki (#F0E68C)
+255 250 205    lemonchiffon (#FFFACD)
+238 232 170    palegoldenrod (#EEE8AA)
+189 183 107    darkkhaki (#BDB76B)
+245 245 220    beige (#F5F5DC)
+250 250 210    lightgoldenrodyellow (#FAFAD2)
+128 128   0    olive (#808000)
+255 255   0    yellow (#FFFF00)
+255 255 224    lightyellow (#FFFFE0)
+255 255 240    ivory (#FFFFF0)
+107 142  35    olivedrab (#6B8E23)
+154 205  50    yellowgreen (#9ACD32)
+ 85 107  47    darkolivegreen (#556B2F)
+173 255  47    greenyellow (#ADFF2F)
+127 255   0    chartreuse (#7FFF00)
+124 252   0    lawngreen (#7CFC00)
+143 188 143    darkseagreen (#8FBC8F)
+ 34 139  34    forestgreen (#228B22)
+ 50 205  50    limegreen (#32CD32)
+144 238 144    lightgreen (#90EE90)
+152 251 152    palegreen (#98FB98)
+  0 100   0    darkgreen (#006400)
+  0 128   0    green (#008000)
+  0 255   0    lime (#00FF00)
+240 255 240    honeydew (#F0FFF0)
+ 46 139  87    seagreen (#2E8B57)
+ 60 179 113    mediumseagreen (#3CB371)
+  0 255 127    springgreen (#00FF7F)
+245 255 250    mintcream (#F5FFFA)
+  0 250 154    mediumspringgreen (#00FA9A)
+102 205 170    mediumaquamarine (#66CDAA)
+127 255 212    aquamarine (#7FFFD4)
+ 64 224 208    turquoise (#40E0D0)
+ 32 178 170    lightseagreen (#20B2AA)
+ 72 209 204    mediumturquoise (#48D1CC)
+ 47  79  79    darkslategray (#2F4F4F)
+175 238 238    paleturquoise (#AFEEEE)
+  0 128 128    teal (#008080)
+  0 139 139    darkcyan (#008B8B)
+  0 255 255    cyan (#00FFFF)
+224 255 255    lightcyan (#E0FFFF)
+240 255 255    azure (#F0FFFF)
+  0 206 209    darkturquoise (#00CED1)
+ 95 158 160    cadetblue (#5F9EA0)
+176 224 230    powderblue (#B0E0E6)
+173 216 230    lightblue (#ADD8E6)
+  0 191 255    deepskyblue (#00BFFF)
+135 206 235    skyblue (#87CEEB)
+135 206 250    lightskyblue (#87CEFA)
+ 70 130 180    steelblue (#4682B4)
+240 248 255    aliceblue (#F0F8FF)
+ 30 144 255    dodgerblue (#1E90FF)
+112 128 144    slategray (#708090)
+119 136 153    lightslategray (#778899)
+176 196 222    lightsteelblue (#B0C4DE)
+100 149 237    cornflowerblue (#6495ED)
+ 65 105 225    royalblue (#4169E1)
+ 25  25 112    midnightblue (#191970)
+230 230 250    lavender (#E6E6FA)
+  0   0 128    navy (#000080)
+  0   0 139    darkblue (#00008B)
+  0   0 205    mediumblue (#0000CD)
+  0   0 255    blue (#0000FF)
+248 248 255    ghostwhite (#F8F8FF)
+106  90 205    slateblue (#6A5ACD)
+ 72  61 139    darkslateblue (#483D8B)
+123 104 238    mediumslateblue (#7B68EE)
+147 112 219    mediumpurple (#9370DB)
+138  43 226    blueviolet (#8A2BE2)
+ 75   0 130    indigo (#4B0082)
+153  50 204    darkorchid (#9932CC)
+148   0 211    darkviolet (#9400D3)
+186  85 211    mediumorchid (#BA55D3)
+216 191 216    thistle (#D8BFD8)
+221 160 221    plum (#DDA0DD)
+238 130 238    violet (#EE82EE)
+128   0 128    purple (#800080)
+139   0 139    darkmagenta (#8B008B)
+255   0 255    magenta (#FF00FF)
+218 112 214    orchid (#DA70D6)
+199  21 133    mediumvioletred (#C71585)
+255  20 147    deeppink (#FF1493)
+255 105 180    hotpink (#FF69B4)
+255 240 245    lavenderblush (#FFF0F5)
+219 112 147    palevioletred (#DB7093)
+220  20  60    crimson (#DC143C)
+255 192 203    pink (#FFC0CB)
+255 182 193    lightpink (#FFB6C1)
+102  51 153     rebeccapurple (#663399)
diff --git a/plugins/color-picker/gb-color-picker-document-monitor.c 
b/plugins/color-picker/gb-color-picker-document-monitor.c
new file mode 100644
index 0000000..cc0b24d
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-document-monitor.c
@@ -0,0 +1,575 @@
+/* gb-color-picker-document-monitor.c
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-color-picker-helper.h"
+#include "gb-color-picker-private.h"
+#include "gstyle-color-item.h"
+
+#include "gb-color-picker-document-monitor.h"
+
+struct _GbColorPickerDocumentMonitor
+{
+  GObject       parent_instance;
+
+  IdeBuffer    *buffer;
+
+  gulong        insert_handler_id;
+  gulong        insert_after_handler_id;
+  gulong        delete_handler_id;
+  gulong        delete_after_handler_id;
+  gulong        cursor_notify_handler_id;
+
+  gulong        remove_tag_handler_id;
+
+  guint         is_in_user_action : 1;
+};
+
+G_DEFINE_TYPE (GbColorPickerDocumentMonitor, gb_color_picker_document_monitor, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_BUFFER,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+enum {
+  COLOR_FOUND,
+  LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL];
+
+static void
+block_signals (GbColorPickerDocumentMonitor *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+
+  g_signal_handler_block (self->buffer, self->cursor_notify_handler_id);
+  g_signal_handler_block (self->buffer, self->insert_handler_id);
+  g_signal_handler_block (self->buffer, self->insert_after_handler_id);
+  g_signal_handler_block (self->buffer, self->delete_handler_id);
+  g_signal_handler_block (self->buffer, self->delete_after_handler_id);
+}
+
+static void
+unblock_signals (GbColorPickerDocumentMonitor *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+
+  g_signal_handler_unblock (self->buffer, self->cursor_notify_handler_id);
+  g_signal_handler_unblock (self->buffer, self->insert_handler_id);
+  g_signal_handler_unblock (self->buffer, self->insert_after_handler_id);
+  g_signal_handler_unblock (self->buffer, self->delete_handler_id);
+  g_signal_handler_unblock (self->buffer, self->delete_after_handler_id);
+}
+
+void
+gb_color_picker_document_monitor_set_color_tag_at_cursor (GbColorPickerDocumentMonitor *self,
+                                                          GstyleColor                  *color)
+{
+  GtkTextMark *insert;
+  GtkTextIter cursor;
+
+  g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_return_if_fail (GSTYLE_IS_COLOR (color));
+  g_return_if_fail (self->buffer != NULL);
+
+  insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(self->buffer));
+  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER(self->buffer), &cursor, insert);
+
+  if (!self->is_in_user_action)
+    {
+      gtk_text_buffer_begin_user_action (GTK_TEXT_BUFFER (self->buffer));
+      self->is_in_user_action = TRUE;
+    }
+
+  block_signals (self);
+  gb_color_picker_helper_set_color_tag_at_iter (&cursor, color, TRUE);
+  unblock_signals (self);
+}
+
+static void
+remove_color_tag_foreach_cb (GtkTextTag *tag,
+                             GPtrArray  *taglist)
+{
+  const gchar *name;
+
+  g_assert (GTK_IS_TEXT_TAG (tag));
+  g_assert (taglist != NULL);
+
+  g_object_get (G_OBJECT (tag), "name", &name, NULL);
+  if (!ide_str_empty0 (name) && g_str_has_prefix (name, COLOR_TAG_PREFIX))
+    g_ptr_array_add (taglist, tag);
+}
+
+void
+gb_color_picker_document_monitor_uncolorize (GbColorPickerDocumentMonitor *self,
+                                             GtkTextIter                  *begin,
+                                             GtkTextIter                  *end)
+{
+  g_autoptr (GPtrArray) taglist = NULL;
+  g_autofree gchar *name = NULL;
+  g_autoptr (GSList) tags = NULL;
+  GtkTextTagTable *tag_table;
+  GtkTextIter real_begin;
+  GtkTextIter real_end;
+  GtkTextTag *color_tag;
+  GtkTextTag *tag;
+  GSList *l;
+  gint n;
+
+  g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_return_if_fail (self->buffer != NULL);
+
+  tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (self->buffer));
+  if (begin == NULL && end == NULL)
+    {
+      taglist = g_ptr_array_new ();
+      gtk_text_tag_table_foreach (tag_table, (GtkTextTagTableForeach)remove_color_tag_foreach_cb, taglist);
+      for (n = 0; n < taglist->len; ++n)
+        gtk_text_tag_table_remove (tag_table, g_ptr_array_index (taglist, n));
+
+      return;
+    }
+
+  if (begin == NULL)
+    gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (self->buffer), &real_begin);
+  else
+    real_begin = *begin;
+
+  if (end == NULL)
+    gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (self->buffer), &real_end);
+  else
+    real_end = *end;
+
+  while (TRUE)
+    {
+      color_tag = NULL;
+      tags = gtk_text_iter_get_toggled_tags (&real_begin, TRUE);
+      for (l = tags; l != NULL; l = g_slist_next (l))
+        {
+          tag = l->data;
+          g_object_get (G_OBJECT (tag), "name", &name, NULL);
+          if (!ide_str_empty0 (name) && g_str_has_prefix (name, COLOR_TAG_PREFIX))
+            {
+              color_tag = tag;
+              break;
+            }
+        }
+
+      if (color_tag != NULL)
+        {
+          gtk_text_iter_forward_to_tag_toggle (&real_begin, color_tag);
+          gtk_text_tag_table_remove (tag_table, color_tag);
+        }
+
+      if (!gtk_text_iter_forward_to_tag_toggle (&real_begin, NULL))
+        break;
+
+      if (gtk_text_iter_compare (&real_begin, &real_end) != -1)
+        break;
+    }
+}
+
+void
+gb_color_picker_document_monitor_colorize (GbColorPickerDocumentMonitor *self,
+                                           GtkTextIter                  *begin,
+                                           GtkTextIter                  *end)
+{
+  g_autofree gchar *text = NULL;
+  g_autoptr(GPtrArray) items = NULL;
+  GstyleColorItem *item;
+  GstyleColor *color;
+  GtkTextTag *tag;
+  GtkTextIter real_begin;
+  GtkTextIter real_end;
+  GtkTextIter tag_begin;
+  GtkTextIter tag_end;
+  gint offset;
+  gint len;
+  gint n;
+  gint pos;
+
+  g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_return_if_fail (self->buffer != NULL);
+
+  if (begin == NULL)
+    gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (self->buffer), &real_begin);
+  else
+    real_begin = *begin;
+
+  if (end == NULL)
+    gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (self->buffer), &real_end);
+  else
+    real_end = *end;
+
+  if (gtk_text_iter_equal (&real_begin, &real_end))
+    return;
+
+  offset = gtk_text_iter_get_offset (&real_begin);
+  text = gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (self->buffer), &real_begin, &real_end, TRUE);
+
+  items = gstyle_color_parse (text);
+  for (n = 0; n < items->len; ++n)
+    {
+      item = g_ptr_array_index (items, n);
+      pos = offset + gstyle_color_item_get_start (item);
+      gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (self->buffer), &tag_begin, pos);
+      len = gstyle_color_item_get_len (item);
+      gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (self->buffer), &tag_end, pos + len);
+      color = (GstyleColor *)gstyle_color_item_get_color (item);
+
+      tag = gb_color_picker_helper_create_color_tag (GTK_TEXT_BUFFER (self->buffer), color);
+      gtk_text_buffer_apply_tag (GTK_TEXT_BUFFER (self->buffer), tag, &tag_begin, &tag_end);
+      /* FIXME: is the tag added to the tag table or should we handle a hash table/tag table ourself ? */
+    }
+}
+
+static void
+text_inserted_cb (GbColorPickerDocumentMonitor *self,
+                  GtkTextIter                  *cursor,
+                  gchar                        *text,
+                  gint                          len,
+                  GtkTextBuffer                *buffer)
+{
+  GtkTextTag *tag;
+  GstyleColor *color;
+  GtkTextIter begin, end;
+
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+  g_assert (cursor != NULL);
+
+  tag = gb_color_picker_helper_get_tag_at_iter (cursor, &color, &begin, &end);
+  if (tag != NULL )
+    {
+      gtk_text_iter_set_line_offset (&begin, 0);
+      if (!gtk_text_iter_ends_line (&end))
+        gtk_text_iter_forward_to_line_end (&end);
+
+      gb_color_picker_document_monitor_uncolorize (self, &begin, &end);
+    }
+}
+
+static void
+text_inserted_after_cb (GbColorPickerDocumentMonitor *self,
+                        GtkTextIter                  *iter,
+                        gchar                        *text,
+                        gint                          len,
+                        GtkTextBuffer                *buffer)
+{
+  GtkTextIter begin, end;
+  gint offset;
+
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+  g_assert (iter != NULL);
+
+  begin = *iter;
+  offset = gtk_text_iter_get_offset (&begin);
+  gtk_text_iter_set_offset (&begin, offset - len);
+  gtk_text_iter_set_line_offset (&begin, 0);
+
+  end = *iter;
+  if (!gtk_text_iter_ends_line (&end))
+    gtk_text_iter_forward_to_line_end (&end);
+
+  gb_color_picker_document_monitor_colorize (self, &begin, &end);
+}
+
+static void
+remove_tag_cb (GbColorPickerDocumentMonitor *self,
+               GtkTextTag                   *tag,
+               GtkTextIter                  *start,
+               GtkTextIter                  *end,
+               GtkTextBuffer                *buffer)
+{
+  GtkTextTagTable *tag_table;
+  g_autofree gchar *name = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+  g_assert (GTK_IS_TEXT_TAG (tag));
+
+  tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (self->buffer));
+  g_object_get (G_OBJECT (tag), "name", &name, NULL);
+
+  if (!ide_str_empty0 (name) &&
+      g_str_has_prefix (name, COLOR_TAG_PREFIX) &&
+      gtk_text_tag_table_lookup (tag_table, name))
+    {
+      gtk_text_tag_table_remove (tag_table, tag);
+    }
+}
+
+static void
+text_deleted_cb (GbColorPickerDocumentMonitor *self,
+                 GtkTextIter                  *begin,
+                 GtkTextIter                  *end,
+                 GtkTextBuffer                *buffer)
+{
+  GtkTextIter recolor_begin;
+  GtkTextIter recolor_end;
+
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+
+  self->remove_tag_handler_id = g_signal_connect_object (GTK_TEXT_BUFFER (self->buffer),
+                                                         "remove-tag",
+                                                         G_CALLBACK (remove_tag_cb),
+                                                         self,
+                                                         G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+  recolor_begin = *begin;
+  gtk_text_iter_set_line_offset (&recolor_begin, 0);
+
+  recolor_end = *end;
+  if (!gtk_text_iter_ends_line (&recolor_end))
+    gtk_text_iter_forward_to_line_end (&recolor_end);
+
+  /* FIXME: we only need to remove color tag */
+  gtk_text_buffer_remove_all_tags (buffer, &recolor_begin, &recolor_end);
+  g_signal_handler_disconnect (GTK_TEXT_BUFFER (self->buffer), self->remove_tag_handler_id);
+}
+
+static void
+text_deleted_after_cb (GbColorPickerDocumentMonitor *self,
+                       GtkTextIter                  *begin,
+                       GtkTextIter                  *end,
+                       GtkTextBuffer                *buffer)
+{
+  GtkTextIter recolor_begin;
+  GtkTextIter recolor_end;
+
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+
+  recolor_begin = *begin;
+  gtk_text_iter_set_line_offset (&recolor_begin, 0);
+
+  recolor_end = *end;
+  if (!gtk_text_iter_ends_line (&recolor_end))
+    gtk_text_iter_forward_to_line_end (&recolor_end);
+
+  gb_color_picker_document_monitor_colorize (self, &recolor_begin, &recolor_end);
+}
+
+static void
+cursor_moved_cb (GbColorPickerDocumentMonitor *self,
+                 GParamSpec                   *prop,
+                 GtkTextBuffer                *buffer)
+{
+  GtkTextTag *tag;
+  GtkTextMark *insert;
+  GtkTextIter cursor;
+  GstyleColor *current_color;
+  GtkTextIter begin, end;
+
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+
+  if (self->is_in_user_action)
+    {
+      gtk_text_buffer_end_user_action (GTK_TEXT_BUFFER (self->buffer));
+      self->is_in_user_action = FALSE;
+    }
+
+  insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER(self->buffer));
+  gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER(self->buffer), &cursor, insert);
+
+  /* TODO: fast path: check if we are in the last already detected color tag */
+  tag = gb_color_picker_helper_get_tag_at_iter (&cursor, &current_color, &begin, &end);
+  if (tag != NULL)
+    g_signal_emit (self, signals [COLOR_FOUND], 0, current_color);
+}
+
+static void
+start_monitor (GbColorPickerDocumentMonitor *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+
+  self->insert_handler_id = g_signal_connect_object (GTK_TEXT_BUFFER (self->buffer),
+                                                     "insert-text",
+                                                     G_CALLBACK (text_inserted_cb),
+                                                     self,
+                                                     G_CONNECT_SWAPPED);
+
+  self->insert_after_handler_id = g_signal_connect_object (GTK_TEXT_BUFFER (self->buffer),
+                                                           "insert-text",
+                                                           G_CALLBACK (text_inserted_after_cb),
+                                                           self,
+                                                           G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+  self->delete_handler_id = g_signal_connect_object (GTK_TEXT_BUFFER (self->buffer),
+                                                     "delete-range",
+                                                     G_CALLBACK (text_deleted_cb),
+                                                     self,
+                                                     G_CONNECT_SWAPPED);
+
+  self->delete_after_handler_id = g_signal_connect_object (GTK_TEXT_BUFFER (self->buffer),
+                                                           "delete-range",
+                                                           G_CALLBACK (text_deleted_after_cb),
+                                                           self,
+                                                           G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+  self->cursor_notify_handler_id = g_signal_connect_object (GTK_TEXT_BUFFER (self->buffer),
+                                                            "notify::cursor-position",
+                                                            G_CALLBACK (cursor_moved_cb),
+                                                            self,
+                                                            G_CONNECT_SWAPPED);
+}
+
+static void
+stop_monitor (GbColorPickerDocumentMonitor *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+
+  g_signal_handlers_disconnect_by_func (self->buffer, text_inserted_cb, self);
+  g_signal_handlers_disconnect_by_func (self->buffer, text_inserted_after_cb, self);
+  g_signal_handlers_disconnect_by_func (self->buffer, text_deleted_cb, self);
+  g_signal_handlers_disconnect_by_func (self->buffer, text_deleted_after_cb, self);
+  g_signal_handlers_disconnect_by_func (self->buffer, cursor_moved_cb, self);
+}
+
+void
+gb_color_picker_document_monitor_set_buffer (GbColorPickerDocumentMonitor *self,
+                                             IdeBuffer                    *buffer)
+{
+  g_return_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_return_if_fail (IDE_IS_BUFFER (buffer));
+
+  if (self->buffer != buffer)
+    {
+      self->buffer = buffer;
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_BUFFER]);
+
+      if (buffer != NULL)
+        start_monitor (self);
+      else
+        stop_monitor (self);
+    }
+}
+
+IdeBuffer *
+gb_color_picker_document_monitor_get_buffer (GbColorPickerDocumentMonitor *self)
+{
+  g_return_val_if_fail (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self), NULL);
+
+  return self->buffer;
+}
+
+GbColorPickerDocumentMonitor *
+gb_color_picker_document_monitor_new (IdeBuffer *buffer)
+{
+  return g_object_new (GB_TYPE_COLOR_PICKER_DOCUMENT_MONITOR,
+                       "buffer", buffer,
+                       NULL);
+}
+
+static void
+gb_color_picker_document_monitor_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (gb_color_picker_document_monitor_parent_class)->finalize (object);
+}
+
+static void
+gb_color_picker_document_monitor_get_property (GObject    *object,
+                                               guint       prop_id,
+                                               GValue     *value,
+                                               GParamSpec *pspec)
+{
+  GbColorPickerDocumentMonitor *self = GB_COLOR_PICKER_DOCUMENT_MONITOR (object);
+
+
+  switch (prop_id)
+    {
+    case PROP_BUFFER:
+      g_value_set_object (value, gb_color_picker_document_monitor_get_buffer (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_color_picker_document_monitor_set_property (GObject      *object,
+                                               guint         prop_id,
+                                               const GValue *value,
+                                               GParamSpec   *pspec)
+{
+  GbColorPickerDocumentMonitor *self = GB_COLOR_PICKER_DOCUMENT_MONITOR (object);
+
+  switch (prop_id)
+    {
+    case PROP_BUFFER:
+      gb_color_picker_document_monitor_set_buffer (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+color_found_handler_cb (GbColorPickerDocumentMonitor *self,
+                        GstyleColor                  *color)
+{
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (self));
+  g_assert (GSTYLE_IS_COLOR (color));
+
+  g_object_unref (color);
+}
+
+static void
+gb_color_picker_document_monitor_class_init (GbColorPickerDocumentMonitorClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gb_color_picker_document_monitor_finalize;
+  object_class->get_property = gb_color_picker_document_monitor_get_property;
+  object_class->set_property = gb_color_picker_document_monitor_set_property;
+
+  properties[PROP_BUFFER] =
+    g_param_spec_object ("buffer",
+                         "Buffer",
+                         "The GtkTextBuffer for the monitor.",
+                         GTK_TYPE_TEXT_BUFFER,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+/* do not work, try with class offset ? */
+  signals [COLOR_FOUND] = g_signal_new_class_handler ("color-found",
+                                                      G_TYPE_FROM_CLASS (klass),
+                                                      G_SIGNAL_RUN_CLEANUP,
+                                                      G_CALLBACK (color_found_handler_cb),
+                                                      NULL, NULL, NULL,
+                                                      G_TYPE_NONE,
+                                                      1,
+                                                      GSTYLE_TYPE_COLOR);
+}
+
+static void
+gb_color_picker_document_monitor_init (GbColorPickerDocumentMonitor *self)
+{
+}
diff --git a/plugins/color-picker/gb-color-picker-document-monitor.h 
b/plugins/color-picker/gb-color-picker-document-monitor.h
new file mode 100644
index 0000000..75c0fc4
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-document-monitor.h
@@ -0,0 +1,50 @@
+/* gb-color-picker-document-monitor.h
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_DOCUMENT_MONITOR_H
+#define GB_COLOR_PICKER_DOCUMENT_MONITOR_H
+
+#include <glib-object.h>
+#include <ide.h>
+
+#include "gstyle-color.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_COLOR_PICKER_DOCUMENT_MONITOR (gb_color_picker_document_monitor_get_type())
+
+G_DECLARE_FINAL_TYPE (GbColorPickerDocumentMonitor, gb_color_picker_document_monitor, GB, 
COLOR_PICKER_DOCUMENT_MONITOR, GObject)
+
+GbColorPickerDocumentMonitor *gb_color_picker_document_monitor_new                        (IdeBuffer 
*buffer);
+void                          gb_color_picker_document_monitor_colorize                   
(GbColorPickerDocumentMonitor *self,
+                                                                                           GtkTextIter       
           *begin,
+                                                                                           GtkTextIter       
           *end);
+IdeBuffer                    *gb_color_picker_document_monitor_get_buffer                 
(GbColorPickerDocumentMonitor *self);
+void                          gb_color_picker_document_monitor_set_buffer                 
(GbColorPickerDocumentMonitor *self,
+                                                                                           IdeBuffer         
           *buffer);
+
+void                          gb_color_picker_document_monitor_set_color_tag_at_cursor    
(GbColorPickerDocumentMonitor *self,
+                                                                                           GstyleColor       
           *color);
+void                          gb_color_picker_document_monitor_uncolorize                 
(GbColorPickerDocumentMonitor *self,
+                                                                                           GtkTextIter       
           *begin,
+                                                                                           GtkTextIter       
           *end);
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_VIEW_MONITOR_H */
+
diff --git a/plugins/color-picker/gb-color-picker-helper.c b/plugins/color-picker/gb-color-picker-helper.c
new file mode 100644
index 0000000..94e3da2
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-helper.c
@@ -0,0 +1,293 @@
+/* gb-color-picker-helper.c
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+#include <libpeas/peas.h>
+#include "gb-color-picker-private.h"
+#include <ide.h>
+
+#include "gb-color-picker-helper.h"
+
+static guint tag_count = 0;
+
+/* We don't take the alpha part intop account because the
+ * view background can be different depending of the used theme
+ */
+void
+gb_color_picker_helper_get_matching_monochrome (GdkRGBA *src_rgba,
+                                                GdkRGBA *dst_rgba)
+{
+  gdouble brightness;
+
+  g_assert (src_rgba != NULL);
+  g_assert (dst_rgba != NULL);
+
+  /* TODO: take alpha into account */
+
+  brightness = src_rgba->red * 299 + src_rgba->green * 587 + src_rgba->blue * 114;
+  if (brightness > 500)
+    {
+      dst_rgba->red = 0.0;
+      dst_rgba->green = 0.0;
+      dst_rgba->blue = 0.0;
+      dst_rgba->alpha = 1.0;
+    }
+  else
+    {
+      dst_rgba->red = 1.0;
+      dst_rgba->green = 1.0;
+      dst_rgba->blue = 1.0;
+      dst_rgba->alpha = 1.0;
+    }
+}
+
+static inline void
+int_to_str (gchar *str,
+            guint  value)
+{
+  guint i = 1000000000;
+
+  g_assert (str != NULL);
+
+  if (value == 0)
+    i = 1;
+  else
+    while (i > value)
+      i /= 10;
+
+  do
+    {
+      *str = '0' + (value - value % i) / i % 10;
+      ++str;
+      i /= 10;
+    } while (i);
+
+  *str = '\0';
+}
+
+const gchar *
+gb_color_picker_helper_get_color_picker_data_path (void)
+{
+  PeasEngine *engine;
+  PeasPluginInfo *info;
+  const gchar *datadir;
+
+  engine = peas_engine_get_default ();
+  info = peas_engine_get_plugin_info(engine, "color_picker_plugin");
+  datadir = peas_plugin_info_get_data_dir (info);
+
+  return datadir;
+}
+
+GtkTextTag *
+gb_color_picker_helper_create_color_tag (GtkTextBuffer *buffer,
+                                         GstyleColor   *color)
+{
+  gchar str [11];
+  GtkTextTag *tag;
+  g_autofree gchar *name = NULL;
+  GdkRGBA fg_rgba;
+  GdkRGBA bg_rgba;
+
+  g_assert (GTK_IS_TEXT_BUFFER (buffer));
+  g_assert (GSTYLE_IS_COLOR (color));
+
+  int_to_str (str, tag_count);
+
+  gstyle_color_fill_rgba (color, &bg_rgba);
+  bg_rgba.alpha = 1.0;
+
+  gb_color_picker_helper_get_matching_monochrome (&bg_rgba, &fg_rgba);
+  name = g_strconcat (COLOR_TAG_PREFIX, str, NULL);
+  ++tag_count;
+
+  tag = gtk_text_buffer_create_tag (buffer, name,
+                                    "foreground-rgba", &fg_rgba,
+                                    "background-rgba", &bg_rgba,
+                                    NULL);
+
+  return tag;
+}
+
+void
+gb_color_picker_helper_change_color_tag (GtkTextTag    *tag,
+                                         GstyleColor   *color)
+{
+  GdkRGBA fg_rgba;
+  GdkRGBA bg_rgba;
+
+  g_assert (GTK_IS_TEXT_TAG (tag));
+  g_assert (GSTYLE_IS_COLOR (color));
+
+  gstyle_color_fill_rgba (color, &bg_rgba);
+  bg_rgba.alpha = 1.0;
+  
+  gb_color_picker_helper_get_matching_monochrome (&bg_rgba, &fg_rgba);
+
+  g_object_set (G_OBJECT (tag),
+                "foreground-rgba", &fg_rgba,
+                "background-rgba", &bg_rgba,
+                NULL);
+}
+
+GtkTextTag *
+gb_color_picker_helper_get_tag_at_iter (GtkTextIter  *cursor,
+                                        GstyleColor **current_color,
+                                        GtkTextIter  *begin,
+                                        GtkTextIter  *end)
+{
+  GtkTextBuffer *buffer;
+  GtkTextTag *tag;
+  GSList *tags;
+  const gchar *name;
+  g_autofree gchar *color_text = NULL;
+
+  g_assert (cursor != NULL);
+  g_assert (current_color != NULL);
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+
+  tags = gtk_text_iter_get_tags (cursor);
+  if (tags != NULL)
+    {
+      for (; tags != NULL; tags = g_slist_next (tags))
+        {
+          tag = tags->data;
+          g_object_get (G_OBJECT (tag), "name", &name, NULL);
+          if (!ide_str_empty0 (name) && g_str_has_prefix (name, COLOR_TAG_PREFIX))
+            {
+              *begin = *cursor;
+              *end = *cursor;
+              if ((gtk_text_iter_starts_tag (begin, tag) || gtk_text_iter_backward_to_tag_toggle (begin, 
tag)) &&
+                   (gtk_text_iter_ends_tag (end, tag) || gtk_text_iter_forward_to_tag_toggle (end, tag)))
+                {
+                  buffer = gtk_text_iter_get_buffer (cursor);
+                  color_text = gtk_text_buffer_get_text (buffer, begin, end, FALSE);
+                  *current_color = gstyle_color_new_from_string (NULL, color_text);
+                  if (*current_color != NULL)
+                    {
+                      g_slist_free (tags);
+                      return tag;
+                    }
+                }
+            }
+        }
+
+      g_slist_free (tags);
+    }
+
+  *current_color = NULL;
+  return NULL;
+}
+
+GtkTextTag *
+gb_color_picker_helper_set_color_tag (GtkTextIter *begin,
+                                      GtkTextIter *end,
+                                      GstyleColor *color,
+                                      gboolean     preserve_cursor)
+{
+  GtkTextBuffer *buffer;
+  GtkTextTag *tag;
+  g_autofree gchar *tag_text = NULL;
+  GtkTextMark *insert;
+  GtkTextIter cursor;
+  gint cursor_offset;
+
+  g_assert (GSTYLE_IS_COLOR (color));
+  g_assert (begin != NULL);
+  g_assert (end != NULL);
+
+  buffer = gtk_text_iter_get_buffer (begin);
+
+  if (preserve_cursor)
+    {
+      insert = gtk_text_buffer_get_insert (buffer);
+      gtk_text_buffer_get_iter_at_mark (buffer, &cursor, insert);
+      cursor_offset = gtk_text_iter_get_offset (&cursor);
+    }
+
+  tag = gb_color_picker_helper_create_color_tag (buffer, color);
+  tag_text = gstyle_color_to_string (color, GSTYLE_COLOR_KIND_ORIGINAL);
+
+  gtk_text_buffer_delete (buffer, begin, end);
+  gtk_text_buffer_insert_with_tags (buffer, begin, tag_text, -1, tag, NULL);
+
+  /* TODO: remove old tag name from table */
+
+  if (preserve_cursor)
+    {
+      gtk_text_buffer_get_iter_at_offset (buffer, &cursor, cursor_offset);
+      gtk_text_buffer_place_cursor (buffer, &cursor);
+    }
+
+  return tag;
+}
+
+GtkTextTag *
+gb_color_picker_helper_set_color_tag_at_iter (GtkTextIter *iter,
+                                              GstyleColor *color,
+                                              gboolean     preserve_cursor)
+{
+  g_autoptr (GstyleColor) current_color = NULL;
+  g_autofree gchar *new_text = NULL;
+  GtkTextBuffer *buffer;
+  GtkTextTag *tag = NULL;
+  GtkTextIter begin, end;
+  gint cursor_offset;
+  gint start_offset;
+  gint dst_offset;
+
+  g_assert (GSTYLE_IS_COLOR (color));
+  g_assert (iter != NULL);
+
+  tag = gb_color_picker_helper_get_tag_at_iter (iter, &current_color, &begin, &end);
+  if (tag != NULL)
+    {
+      buffer = gtk_text_iter_get_buffer (&begin);
+      new_text = gstyle_color_to_string (color, gstyle_color_get_kind (current_color));
+      if (preserve_cursor)
+        {
+          start_offset = gtk_text_iter_get_line_offset (&begin);
+          cursor_offset = gtk_text_iter_get_line_offset (iter);
+          dst_offset = MIN (cursor_offset, start_offset + strlen (new_text) - 1);
+        }
+
+      gb_color_picker_helper_change_color_tag (tag, color);
+
+      /* TODO: keep tags in tagtable so no need for ref/unref */
+      g_object_ref (tag);
+
+      gtk_text_buffer_delete (buffer, &begin, &end);
+      gtk_text_buffer_insert_with_tags (buffer, &begin, new_text, -1, tag, NULL);
+
+      if (preserve_cursor)
+        {
+          gtk_text_iter_set_line_offset (&begin, dst_offset);
+          gtk_text_buffer_place_cursor (buffer, &begin);
+        }
+
+      g_object_unref (tag);
+      return tag;
+    }
+  else
+    {
+      /* TODO: parse the line, check the limits and set a new tag */
+      return NULL;
+    }
+}
diff --git a/plugins/color-picker/gb-color-picker-helper.h b/plugins/color-picker/gb-color-picker-helper.h
new file mode 100644
index 0000000..13f2817
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-helper.h
@@ -0,0 +1,53 @@
+/*`gb-color-picker-helper.h
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_HELPER_H
+#define GB_COLOR_PICKER_HELPER_H
+
+#include <glib-object.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+#include "gstyle-color.h"
+
+G_BEGIN_DECLS
+
+void                      gb_color_picker_helper_change_color_tag                 (GtkTextTag       *tag,
+                                                                                   GstyleColor      *color);
+GtkTextTag               *gb_color_picker_helper_create_color_tag                 (GtkTextBuffer    *buffer,
+                                                                                   GstyleColor      *color);
+GtkTextTag               *gb_color_picker_helper_get_tag_at_iter                  (GtkTextIter      *cursor,
+                                                                                   GstyleColor     
**current_color,
+                                                                                   GtkTextIter      *begin,
+                                                                                   GtkTextIter      *end);
+const gchar              *gb_color_picker_helper_get_color_picker_data_path       (void);
+void                      gb_color_picker_helper_get_matching_monochrome          (GdkRGBA          
*src_rgba,
+                                                                                   GdkRGBA          
*dst_rgba);
+GtkTextTag               *gb_color_picker_helper_set_color_tag                    (GtkTextIter      *begin,
+                                                                                   GtkTextIter      *end,
+                                                                                   GstyleColor      *color,
+                                                                                   gboolean          
preserve_cursor);
+GtkTextTag               *gb_color_picker_helper_set_color_tag_at_iter            (GtkTextIter      *iter,
+                                                                                   GstyleColor      *color,
+                                                                                   gboolean          
preserve_cursor);
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_HELPER_H */
+
diff --git a/plugins/color-picker/gb-color-picker-plugin.c b/plugins/color-picker/gb-color-picker-plugin.c
new file mode 100644
index 0000000..9902a46
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-plugin.c
@@ -0,0 +1,30 @@
+/* gb-color-picker-plugin.c
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ide.h>
+#include <libpeas/peas.h>
+
+#include "gb-color-picker-workbench-addin.h"
+
+void
+peas_register_types (PeasObjectModule *module)
+{
+  peas_object_module_register_extension_type (module,
+                                              IDE_TYPE_WORKBENCH_ADDIN,
+                                              GB_TYPE_COLOR_PICKER_WORKBENCH_ADDIN);
+}
diff --git a/plugins/color-picker/gb-color-picker-prefs-list.c 
b/plugins/color-picker/gb-color-picker-prefs-list.c
new file mode 100644
index 0000000..4d1fed0
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs-list.c
@@ -0,0 +1,63 @@
+/* gb-color-picker-prefs-list.c
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-color-picker-prefs-list.h"
+
+struct _GbColorPickerPrefsList
+{
+  GtkListBox parent_instance;
+};
+
+G_DEFINE_TYPE (GbColorPickerPrefsList, gb_color_picker_prefs_list, GTK_TYPE_LIST_BOX)
+
+GbColorPickerPrefsList *
+gb_color_picker_prefs_list_new (void)
+{
+  return g_object_new (GB_TYPE_COLOR_PICKER_PREFS_LIST, NULL);
+}
+
+static void
+gb_color_picker_prefs_list_row_activated (GtkListBox      *listbox,
+                                          GtkListBoxRow   *row)
+{
+  GtkWidget *child;
+
+  g_assert (GTK_IS_LIST_BOX (listbox));
+  g_assert (GTK_IS_LIST_BOX_ROW (row));
+
+  child = gtk_bin_get_child (GTK_BIN (row));
+  if (child != NULL)
+    gtk_widget_activate (child);
+}
+
+static void
+gb_color_picker_prefs_list_class_init (GbColorPickerPrefsListClass *klass)
+{
+  GtkListBoxClass *listbox_class = GTK_LIST_BOX_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  listbox_class->row_activated = gb_color_picker_prefs_list_row_activated;
+
+  gtk_widget_class_set_css_name (widget_class, "gbcolorpickerprefslist");
+}
+
+static void
+gb_color_picker_prefs_list_init (GbColorPickerPrefsList *self)
+{
+  g_object_set (G_OBJECT (self), "selection-mode", GTK_SELECTION_NONE, NULL);
+}
diff --git a/plugins/color-picker/gb-color-picker-prefs-list.h 
b/plugins/color-picker/gb-color-picker-prefs-list.h
new file mode 100644
index 0000000..e7c74ad
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs-list.h
@@ -0,0 +1,36 @@
+/* gb-color-picker-prefs-list.h
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_PREFS_LIST_H
+#define GB_COLOR_PICKER_PREFS_LIST_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_COLOR_PICKER_PREFS_LIST (gb_color_picker_prefs_list_get_type())
+
+G_DECLARE_FINAL_TYPE (GbColorPickerPrefsList, gb_color_picker_prefs_list, GB, COLOR_PICKER_PREFS_LIST, 
GtkListBox)
+
+GbColorPickerPrefsList *gb_color_picker_prefs_list_new (void);
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_PREFS_LIST_H */
+
diff --git a/plugins/color-picker/gb-color-picker-prefs-palette-list.c 
b/plugins/color-picker/gb-color-picker-prefs-palette-list.c
new file mode 100644
index 0000000..c2db381
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs-palette-list.c
@@ -0,0 +1,210 @@
+/* gb-color-picker-prefs-palette-list.c
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-color-picker-prefs-palette-row.h"
+
+#include "gb-color-picker-prefs-palette-list.h"
+
+struct _GbColorPickerPrefsPaletteList
+{
+  GtkBox         parent_instance;
+
+  GtkListBox    *list_box;
+  GtkListBoxRow *plus_row;
+  GtkWidget     *plus_button;
+};
+
+G_DEFINE_TYPE (GbColorPickerPrefsPaletteList, gb_color_picker_prefs_palette_list, GTK_TYPE_BOX)
+
+enum {
+  ADDED,
+  LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL];
+
+GbColorPickerPrefsPaletteList *
+gb_color_picker_prefs_palette_list_new (void)
+{
+  return g_object_new (GB_TYPE_COLOR_PICKER_PREFS_PALETTE_LIST, NULL);
+}
+
+GtkListBox *
+gb_color_picker_prefs_palette_list_get_list_box (GbColorPickerPrefsPaletteList *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (self));
+
+  return self->list_box;
+}
+
+static void
+gb_color_picker_prefs_palette_list_row_plus_button_pressed_cb (GbColorPickerPrefsPaletteList *self,
+                                                               GtkButton                     *button)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  g_signal_emit (self, signals [ADDED], 0);
+}
+
+static void
+gb_color_picker_prefs_palette_list_row_activated_cb (GbColorPickerPrefsPaletteList *self,
+                                                     GtkListBoxRow                 *row,
+                                                     GtkListBox                    *listbox)
+{
+  GtkWidget *child;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (self));
+  g_assert (GTK_IS_LIST_BOX (listbox));
+  g_assert (GTK_IS_LIST_BOX_ROW (row));
+
+  child = gtk_bin_get_child (GTK_BIN (row));
+  if (child != NULL)
+    gtk_widget_activate (child);
+}
+
+static gboolean
+gb_picker_prefs_palette_list_key_pressed_cb (GbColorPickerPrefsPaletteList *self,
+                                             GdkEventKey                   *event,
+                                             GtkListBox                    *list_box)
+{
+  GtkWidget *toplevel;
+  GtkWidget *focused_widget;
+  GtkWidget *row_child;
+  gboolean is_editing;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (self));
+  g_assert (event != NULL);
+  g_assert (GTK_IS_LIST_BOX (list_box));
+
+  toplevel = gtk_widget_get_toplevel (GTK_WIDGET (list_box));
+  if (!gtk_widget_is_toplevel (toplevel) || event->type != GDK_KEY_PRESS)
+    return GDK_EVENT_PROPAGATE;
+
+  focused_widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
+  if (gtk_widget_get_parent (focused_widget) == GTK_WIDGET (list_box))
+    {
+      row_child = gtk_bin_get_child (GTK_BIN (focused_widget));
+      if (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (row_child))
+        {
+          g_object_get (G_OBJECT (row_child), "is-editing", &is_editing, NULL);
+          if (!is_editing && event->keyval == GDK_KEY_F2)
+            {
+              g_signal_emit_by_name (row_child, "edit");
+              return GDK_EVENT_STOP;
+            }
+        }
+    }
+  else if (GTK_IS_ENTRY (focused_widget))
+    {
+       if (gtk_widget_is_ancestor (focused_widget, GTK_WIDGET (list_box)) &&
+           is_editing &&
+           event->keyval == GDK_KEY_Escape)
+        {
+          row_child = gtk_widget_get_ancestor (focused_widget, GTK_TYPE_LIST_BOX_ROW);
+          if (row_child != NULL)
+            gtk_widget_grab_focus (row_child);
+        }
+
+      return GDK_EVENT_STOP;
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+gb_color_picker_prefs_palette_list_add (GtkContainer *container,
+                                        GtkWidget    *widget)
+{
+  GbColorPickerPrefsPaletteList *self = (GbColorPickerPrefsPaletteList *)container;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (self));
+  g_assert (GTK_IS_WIDGET (widget));
+
+  gtk_list_box_insert (self->list_box, widget, -1);
+}
+
+static void
+gb_color_picker_prefs_palette_list_init_ui (GbColorPickerPrefsPaletteList *self)
+{
+  GtkStyleContext *context;
+  GtkWidget *scrolled_window;
+  GtkWidget *image;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (self));
+
+  image = gtk_image_new_from_icon_name ("list-add-symbolic", GTK_ICON_SIZE_MENU);
+  self->plus_button = gtk_button_new ();
+
+  gtk_widget_set_hexpand (self->plus_button, TRUE);
+  gtk_container_add (GTK_CONTAINER (self->plus_button), image);
+
+  context = gtk_widget_get_style_context (self->plus_button);
+  gtk_style_context_add_class (context, "flat");
+
+  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, 
GTK_POLICY_AUTOMATIC);
+
+  self->list_box = GTK_LIST_BOX (gtk_list_box_new ());
+  gtk_list_box_set_selection_mode (self->list_box, GTK_SELECTION_NONE);
+  gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (self->list_box));
+
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL);
+  /* As we overwrite the add vfunc we need to call its parent */
+  GTK_CONTAINER_CLASS (gb_color_picker_prefs_palette_list_parent_class)->add (GTK_CONTAINER (self), 
self->plus_button);
+  GTK_CONTAINER_CLASS (gb_color_picker_prefs_palette_list_parent_class)->add (GTK_CONTAINER (self), 
scrolled_window);
+
+  gtk_widget_show_all (GTK_WIDGET (self));
+}
+static void
+gb_color_picker_prefs_palette_list_class_init (GbColorPickerPrefsPaletteListClass *klass)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+  signals [ADDED] =
+    g_signal_new ("added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  0);
+
+  container_class->add = gb_color_picker_prefs_palette_list_add;
+
+  gtk_widget_class_set_css_name (widget_class, "gbcolorpickerprefspalettelist");
+}
+
+static void
+gb_color_picker_prefs_palette_list_init (GbColorPickerPrefsPaletteList *self)
+{
+  gb_color_picker_prefs_palette_list_init_ui (self);
+
+  g_signal_connect_swapped (self->list_box, "row-activated",
+                            G_CALLBACK (gb_color_picker_prefs_palette_list_row_activated_cb),
+                            self);
+
+  g_signal_connect_swapped (self->list_box, "key-press-event",
+                            G_CALLBACK (gb_picker_prefs_palette_list_key_pressed_cb),
+                            self);
+
+  g_signal_connect_swapped (self->plus_button, "pressed",
+                            G_CALLBACK (gb_color_picker_prefs_palette_list_row_plus_button_pressed_cb),
+                            self);
+}
diff --git a/plugins/color-picker/gb-color-picker-prefs-palette-list.h 
b/plugins/color-picker/gb-color-picker-prefs-palette-list.h
new file mode 100644
index 0000000..6b99d2d
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs-palette-list.h
@@ -0,0 +1,37 @@
+/* gb-color-picker-prefs-palette-list.h
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_PREFS_PALETTE_LIST_H
+#define GB_COLOR_PICKER_PREFS_PALETTE_LIST_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_COLOR_PICKER_PREFS_PALETTE_LIST (gb_color_picker_prefs_palette_list_get_type())
+
+G_DECLARE_FINAL_TYPE (GbColorPickerPrefsPaletteList, gb_color_picker_prefs_palette_list, GB, 
COLOR_PICKER_PREFS_PALETTE_LIST, GtkBox)
+
+GbColorPickerPrefsPaletteList    *gb_color_picker_prefs_palette_list_new             (void);
+GtkListBox                       *gb_color_picker_prefs_palette_list_get_list_box    
(GbColorPickerPrefsPaletteList     *self);
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_PREFS_PALETTE_LIST_H */
+
diff --git a/plugins/color-picker/gb-color-picker-prefs-palette-row.c 
b/plugins/color-picker/gb-color-picker-prefs-palette-row.c
new file mode 100644
index 0000000..d26e236
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs-palette-row.c
@@ -0,0 +1,486 @@
+/* gb-color-picker-prefs-palette-row.c
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gdk/gdk.h>
+
+#include <ide.h>
+
+#include "gb-color-picker-prefs-palette-row.h"
+
+struct _GbColorPickerPrefsPaletteRow
+{
+  IdePreferencesBin  parent_instance;
+
+  GtkEntry          *palette_name;
+  GtkButton         *button;
+  GtkImage          *image;
+  GtkWidget         *event_box;
+  gchar             *palette_id;
+  gchar             *backup_name;
+
+  gulong             handler;
+
+  gchar             *key;
+  GVariant          *target;
+  GSettings         *settings;
+
+  guint              updating : 1;
+  guint              is_editing : 1;
+};
+
+G_DEFINE_TYPE (GbColorPickerPrefsPaletteRow, gb_color_picker_prefs_palette_row, IDE_TYPE_PREFERENCES_BIN)
+
+enum {
+  PROP_0,
+  PROP_KEY,
+  PROP_IS_EDITING,
+  PROP_TARGET,
+  PROP_PALETTE_NAME,
+  N_PROPS
+};
+
+enum {
+  ACTIVATED,
+  CLOSED,
+  EDIT,
+  NAME_CHANGED,
+  LAST_SIGNAL
+};
+
+static GParamSpec *properties [N_PROPS];
+static guint signals [LAST_SIGNAL];
+
+static void
+gb_color_picker_prefs_palette_row_changed (GbColorPickerPrefsPaletteRow *self,
+                                           const gchar                  *key,
+                                           GSettings                    *settings)
+{
+  g_autoptr (GVariant) value = NULL;
+  gboolean active;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (key != NULL);
+  g_assert (G_IS_SETTINGS (settings));
+
+  if (self->target == NULL)
+    {
+      gtk_widget_set_visible (GTK_WIDGET (self->image), FALSE);
+      return;
+    }
+
+  if (self->updating == TRUE)
+    return;
+
+  value = g_settings_get_value (settings, key);
+  if (g_variant_is_of_type (value, g_variant_get_type (self->target)))
+    {
+      active = (g_variant_equal (value, self->target));
+      gtk_widget_set_visible (GTK_WIDGET (self->image), active);
+    }
+  else
+    g_warning ("Value and target must be of the same type");
+}
+
+static void
+gb_color_picker_prefs_palette_row_activate (GbColorPickerPrefsPaletteRow *self)
+{
+  g_autoptr (GVariant) value = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (self->target != NULL);
+
+  if (!gtk_widget_get_sensitive (GTK_WIDGET (self)) || self->settings == NULL || self->updating)
+    return;
+
+  value = g_settings_get_value (self->settings, self->key);
+  if (g_variant_is_of_type (value, g_variant_get_type (self->target)))
+    {
+      if (!g_variant_equal (value, self->target))
+        {
+          self->updating = TRUE;
+          g_settings_set_value (self->settings, self->key, self->target);
+          gtk_widget_set_visible (GTK_WIDGET (self->image), TRUE);
+          self->updating = FALSE;
+        }
+    }
+  else
+    g_warning ("Value and target must be of the same type");
+}
+
+static void
+gb_color_picker_prefs_palette_row_edit (GbColorPickerPrefsPaletteRow *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+
+  gtk_entry_grab_focus_without_selecting (self->palette_name);
+  gtk_editable_set_position (GTK_EDITABLE (self->palette_name), -1);
+}
+
+static void
+gb_color_picker_prefs_palette_row_set_edit (GbColorPickerPrefsPaletteRow *self,
+                                            gboolean                      is_editing)
+{
+  GtkWidget *parent;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+
+  if (is_editing)
+    g_signal_emit_by_name (self, "edit");
+  else
+    {
+      parent = gtk_widget_get_parent (GTK_WIDGET (self));
+      gtk_widget_grab_focus (parent);
+    }
+
+  self->is_editing = is_editing;
+}
+
+static void
+gb_color_picker_prefs_palette_row_connect (IdePreferencesBin *bin,
+                                           GSettings         *settings)
+{
+  GbColorPickerPrefsPaletteRow *self = (GbColorPickerPrefsPaletteRow *)bin;
+  g_autofree gchar *signal_detail = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (G_IS_SETTINGS (settings));
+
+  signal_detail = g_strdup_printf ("changed::%s", self->key);
+  self->settings = g_object_ref (settings);
+  self->handler =
+    g_signal_connect_object (settings,
+                             signal_detail,
+                             G_CALLBACK (gb_color_picker_prefs_palette_row_changed),
+                             self,
+                             G_CONNECT_SWAPPED);
+
+  gb_color_picker_prefs_palette_row_changed (self, self->key, settings);
+}
+
+static void
+gb_color_picker_prefs_palette_row_disconnect (IdePreferencesBin *bin,
+                                              GSettings         *settings)
+{
+  GbColorPickerPrefsPaletteRow *self = (GbColorPickerPrefsPaletteRow *)bin;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (G_IS_SETTINGS (settings));
+
+  g_signal_handler_disconnect (settings, self->handler);
+  self->handler = 0;
+  g_clear_object (&self->settings);
+}
+
+static void
+gb_color_picker_prefs_list_row_button_clicked_cb (GbColorPickerPrefsPaletteRow *self,
+                                                  GtkButton                    *button)
+{
+  const gchar *id;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  id = g_variant_get_string (self->target, NULL);
+  g_signal_emit_by_name (self, "closed", id);
+}
+
+static gboolean
+palette_name_activate_cb (GbColorPickerPrefsPaletteRow *self,
+                          GtkEntry                     *palette_name)
+{
+  GtkWidget *parent;
+  const gchar *id;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (GTK_IS_ENTRY (palette_name));
+
+  g_clear_pointer (&self->backup_name, g_free);
+  self->backup_name = g_strdup (gtk_entry_get_text (self->palette_name));
+  id = g_variant_get_string (self->target, NULL);
+  g_signal_emit_by_name (self, "name-changed",
+                         id,
+                         self->backup_name );
+
+  parent = gtk_widget_get_parent (GTK_WIDGET (self));
+  g_assert (GTK_IS_LIST_BOX_ROW (parent));
+  gtk_widget_grab_focus (GTK_WIDGET (parent));
+
+  return GDK_EVENT_STOP;
+}
+
+static gboolean
+event_box_button_pressed_cb (GbColorPickerPrefsPaletteRow *self,
+                             GdkEventButton               *event,
+                             GtkEventBox                  *event_box)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (event != NULL);
+  g_assert (GTK_IS_EVENT_BOX (event_box));
+
+  if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY)
+    {
+      g_signal_emit_by_name (self, "edit");
+      return GDK_EVENT_STOP;
+    }
+
+  return GDK_EVENT_PROPAGATE;
+}
+
+static void
+palette_name_has_focus_cb (GbColorPickerPrefsPaletteRow *self,
+                           GParamSpec                   *pspec,
+                           GtkEntry                     *palette_name)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+  g_assert (pspec != NULL);
+  g_assert (GTK_IS_ENTRY (palette_name));
+
+  self->is_editing = gtk_widget_has_focus (GTK_WIDGET (self->palette_name));
+  g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_IS_EDITING]);
+
+  if (!self->is_editing)
+    {
+      if (g_strcmp0 (self->backup_name, gtk_entry_get_text (self->palette_name)) != 0)
+        {
+          gtk_entry_set_text (self->palette_name, self->backup_name);
+          g_clear_pointer (&self->backup_name, g_free);
+        }
+    }
+  else
+    {
+      g_clear_pointer (&self->backup_name, g_free);
+      self->backup_name = g_strdup (gtk_entry_get_text (self->palette_name));
+    }
+}
+
+static void
+gb_color_picker_prefs_palette_row_set_palette_name (GbColorPickerPrefsPaletteRow *self,
+                                                    const gchar                  *new_text)
+{
+  const gchar *text;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_ROW (self));
+
+  if (ide_str_empty0 (new_text))
+    {
+      gtk_entry_set_text (self->palette_name, "No name");
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PALETTE_NAME]);
+
+      return;
+    }
+
+  text = gtk_entry_get_text (self->palette_name);
+  if (g_strcmp0 (text, new_text) != 0)
+    {
+      gtk_entry_set_text (self->palette_name, new_text);
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PALETTE_NAME]);
+    }
+}
+
+GbColorPickerPrefsPaletteRow *
+gb_color_picker_prefs_palette_row_new (void)
+{
+  return g_object_new (GB_TYPE_COLOR_PICKER_PREFS_PALETTE_ROW, NULL);
+}
+
+static void
+gb_color_picker_prefs_palette_row_finalize (GObject *object)
+{
+  GbColorPickerPrefsPaletteRow *self = (GbColorPickerPrefsPaletteRow *)object;
+
+  if (self->settings != NULL)
+    gb_color_picker_prefs_palette_row_disconnect (IDE_PREFERENCES_BIN (self), self->settings);
+
+  g_clear_pointer (&self->key, g_free);
+  g_clear_pointer (&self->target, g_variant_unref);
+  g_clear_pointer (&self->palette_id, g_free);
+  g_clear_pointer (&self->backup_name, g_free);
+
+  G_OBJECT_CLASS (gb_color_picker_prefs_palette_row_parent_class)->finalize (object);
+}
+
+static void
+gb_color_picker_prefs_palette_row_get_property (GObject    *object,
+                                                guint       prop_id,
+                                                GValue     *value,
+                                                GParamSpec *pspec)
+{
+  GbColorPickerPrefsPaletteRow *self = GB_COLOR_PICKER_PREFS_PALETTE_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_KEY:
+      g_value_set_string (value, self->key);
+      break;
+
+    case PROP_IS_EDITING:
+      g_value_set_boolean (value, self->is_editing);
+      break;
+
+    case PROP_TARGET:
+      g_value_set_variant (value, self->target);
+      break;
+
+    case PROP_PALETTE_NAME:
+      g_value_set_string (value, gtk_entry_get_text (self->palette_name));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_color_picker_prefs_palette_row_set_property (GObject      *object,
+                                                guint         prop_id,
+                                                const GValue *value,
+                                                GParamSpec   *pspec)
+{
+  GbColorPickerPrefsPaletteRow *self = GB_COLOR_PICKER_PREFS_PALETTE_ROW (object);
+
+  switch (prop_id)
+    {
+    case PROP_KEY:
+      self->key = g_value_dup_string (value);
+      break;
+
+    case PROP_IS_EDITING:
+      gb_color_picker_prefs_palette_row_set_edit (self, g_value_get_boolean (value));
+      break;
+
+    case PROP_TARGET:
+      self->target = g_value_dup_variant (value);
+      break;
+
+    case PROP_PALETTE_NAME:
+      gb_color_picker_prefs_palette_row_set_palette_name (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_color_picker_prefs_palette_row_class_init (GbColorPickerPrefsPaletteRowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  IdePreferencesBinClass *bin_class = IDE_PREFERENCES_BIN_CLASS (klass);
+
+  object_class->finalize = gb_color_picker_prefs_palette_row_finalize;
+  object_class->get_property = gb_color_picker_prefs_palette_row_get_property;
+  object_class->set_property = gb_color_picker_prefs_palette_row_set_property;
+
+  bin_class->connect = gb_color_picker_prefs_palette_row_connect;
+  bin_class->disconnect = gb_color_picker_prefs_palette_row_disconnect;
+
+  properties [PROP_IS_EDITING] =
+    g_param_spec_boolean ("is-editing",
+                          "is-editing",
+                          "Whether the row is currently in edit mode or not",
+                          FALSE,
+                          (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_TARGET] =
+    g_param_spec_variant ("target",
+                          "Target",
+                          "Target",
+                          G_VARIANT_TYPE_STRING,
+                          NULL,
+                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_KEY] =
+    g_param_spec_string ("key",
+                         "Key",
+                         "Key",
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
+  properties [PROP_PALETTE_NAME] =
+    g_param_spec_string ("palette-name",
+                         "Palette name",
+                         "Palette name",
+                         NULL,
+                         (G_PARAM_READWRITE |G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  signals [ACTIVATED] =
+    g_signal_new_class_handler ("activated",
+                                G_TYPE_FROM_CLASS (klass),
+                                G_SIGNAL_RUN_LAST,
+                                G_CALLBACK (gb_color_picker_prefs_palette_row_activate),
+                                NULL, NULL, NULL, G_TYPE_NONE, 0);
+  signals [CLOSED] =
+    g_signal_new ("closed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  1,
+                  G_TYPE_POINTER);
+
+  signals [NAME_CHANGED] =
+    g_signal_new ("name-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  2,
+                  G_TYPE_POINTER,
+                  G_TYPE_POINTER);
+
+  signals [EDIT] =
+    g_signal_new_class_handler ("edit",
+                                G_TYPE_FROM_CLASS (klass),
+                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                                G_CALLBACK (gb_color_picker_prefs_palette_row_edit),
+                                NULL, NULL, NULL, G_TYPE_NONE, 0);
+
+  widget_class->activate_signal = signals [ACTIVATED];
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+
+  gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/builder/plugins/color-picker-plugin/gtk/color-picker-palette-row.ui");
+  gtk_widget_class_bind_template_child (widget_class, GbColorPickerPrefsPaletteRow, image);
+  gtk_widget_class_bind_template_child (widget_class, GbColorPickerPrefsPaletteRow, event_box);
+  gtk_widget_class_bind_template_child (widget_class, GbColorPickerPrefsPaletteRow, palette_name);
+  gtk_widget_class_bind_template_child (widget_class, GbColorPickerPrefsPaletteRow, button);
+}
+
+static void
+gb_color_picker_prefs_palette_row_init (GbColorPickerPrefsPaletteRow *self)
+{
+  gtk_widget_init_template (GTK_WIDGET (self));
+  gtk_widget_add_events (self->event_box, GDK_KEY_PRESS_MASK);
+
+  g_signal_connect_swapped (self->event_box, "button-press-event",
+                            G_CALLBACK (event_box_button_pressed_cb),
+                            self);
+
+  g_signal_connect_swapped (self->palette_name, "activate",
+                            G_CALLBACK (palette_name_activate_cb),
+                            self);
+
+  g_signal_connect_swapped (self->palette_name, "notify::has-focus",
+                            G_CALLBACK (palette_name_has_focus_cb),
+                            self);
+
+  g_signal_connect_swapped (self->button, "clicked", G_CALLBACK 
(gb_color_picker_prefs_list_row_button_clicked_cb), self);
+}
diff --git a/plugins/color-picker/gb-color-picker-prefs-palette-row.h 
b/plugins/color-picker/gb-color-picker-prefs-palette-row.h
new file mode 100644
index 0000000..92c892f
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs-palette-row.h
@@ -0,0 +1,36 @@
+/* gb-color-picker-prefs-palette-row.h
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef GB_COLOR_PICKER_PREFS_PALETTE_ROW_H
+#define GB_COLOR_PICKER_PREFS_PALETTE_ROW_H
+
+#include <glib-object.h>
+
+#include "preferences/ide-preferences-bin.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_COLOR_PICKER_PREFS_PALETTE_ROW (gb_color_picker_prefs_palette_row_get_type())
+
+G_DECLARE_FINAL_TYPE (GbColorPickerPrefsPaletteRow, gb_color_picker_prefs_palette_row, GB, 
COLOR_PICKER_PREFS_PALETTE_ROW, IdePreferencesBin)
+
+GbColorPickerPrefsPaletteRow *gb_color_picker_prefs_palette_row_new (void);
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_PREFS_PALETTE_ROW_H */
+
diff --git a/plugins/color-picker/gb-color-picker-prefs.c b/plugins/color-picker/gb-color-picker-prefs.c
new file mode 100644
index 0000000..96dafba
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs.c
@@ -0,0 +1,635 @@
+/* gb-color-picker-prefs.c
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "preferences/ide-preferences-switch.h"
+#include "ide.h"
+
+#include "gb-color-picker-prefs.h"
+#include "gb-color-picker-prefs-list.h"
+#include "gb-color-picker-prefs-palette-list.h"
+#include "gb-color-picker-prefs-palette-row.h"
+
+struct _GbColorPickerPrefs
+{
+  GObject                         parent_instance;
+
+  GtkWidget                      *components_page;
+  GtkWidget                      *color_strings_page;
+  GtkWidget                      *palettes_page;
+  GtkWidget                      *palettes_list_page;
+
+  GstyleColorPanel               *panel;
+  GstylePaletteWidget            *palette_widget;
+  GListStore                     *palettes_store;
+  GbColorPickerPrefsPaletteList  *palettes_box;
+  GtkListBox                     *palettes_listbox;
+
+  GtkWidget                      *load_palette_button;
+  GtkWidget                      *save_palette_button;
+  GtkWidget                      *preview;
+  GtkWidget                      *preview_placeholder;
+  GtkWidget                      *preview_title;
+  GtkWidget                      *preview_palette_widget;
+
+  GtkFileFilter                  *all_files_filter;
+  GtkFileFilter                  *gstyle_files_filter;
+  GtkFileFilter                  *gpl_files_filter;
+  GtkFileFilter                  *builder_files_filter;
+
+  GSettings                      *plugin_settings;
+  GSettings                      *components_settings;
+};
+
+G_DEFINE_TYPE (GbColorPickerPrefs, gb_color_picker_prefs, G_TYPE_OBJECT)
+
+enum
+{
+  PROP_0,
+  PROP_PANEL,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+GtkWidget *
+gb_color_picker_prefs_get_page (GbColorPickerPrefs    *self,
+                                GstyleColorPanelPrefs  prefs_type)
+{
+  g_return_val_if_fail (GB_IS_COLOR_PICKER_PREFS (self), NULL);
+
+  if (prefs_type == GSTYLE_COLOR_PANEL_PREFS_COMPONENTS)
+    return self->components_page;
+  else if (prefs_type == GSTYLE_COLOR_PANEL_PREFS_COLOR_STRINGS)
+    return self->color_strings_page;
+  else if (prefs_type == GSTYLE_COLOR_PANEL_PREFS_PALETTES)
+    return self->palettes_page;
+  else if (prefs_type == GSTYLE_COLOR_PANEL_PREFS_PALETTES_LIST)
+    return self->palettes_list_page;
+  else
+    g_assert_not_reached ();
+}
+
+static GVariant *
+string_to_variant (const gchar *str)
+{
+  GVariant *variant;
+  g_autoptr(GError) error = NULL;
+
+  g_assert (!ide_str_empty0 (str));
+
+  variant = g_variant_parse (NULL, str, NULL, NULL, &error);
+  if (variant == NULL)
+    {
+      g_warning ("%s", error->message);
+      g_error_free (error);
+      return NULL;
+    }
+
+  g_variant_ref_sink (variant);
+  return variant;
+}
+
+static void
+palette_update_preview_cb (GbColorPickerPrefs *self,
+                           GtkDialog          *dialog)
+{
+  g_autoptr (GFile) file = NULL;
+  GstylePalette *palette;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GTK_IS_DIALOG (dialog));
+
+  gstyle_palette_widget_remove_all (GSTYLE_PALETTE_WIDGET (self->preview_palette_widget));
+  file = gtk_file_chooser_get_preview_file (GTK_FILE_CHOOSER (dialog));
+  if (file != NULL)
+    {
+      palette = gstyle_palette_new_from_file (file, NULL, NULL);
+      if (palette != NULL)
+        {
+          gstyle_palette_widget_add (GSTYLE_PALETTE_WIDGET (self->preview_palette_widget), palette);
+          gstyle_palette_widget_show_palette (GSTYLE_PALETTE_WIDGET (self->preview_palette_widget), palette);
+          gtk_label_set_text (GTK_LABEL (self->preview_title), gstyle_palette_get_name (palette));
+
+          return;
+        }
+    }
+
+  gtk_label_set_text (GTK_LABEL (self->preview_title), "");
+}
+
+static void
+palette_dialog_add_preview (GbColorPickerPrefs *self,
+                            GtkWidget          *dialog)
+{
+  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), self->preview);
+  gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (dialog), FALSE);
+
+  g_signal_connect_object (dialog, "update-preview", G_CALLBACK (palette_update_preview_cb), self, 
G_CONNECT_SWAPPED);
+}
+
+static void
+file_dialog_add_filters (GbColorPickerPrefs *self,
+                         GtkWidget          *dialog)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), self->all_files_filter);
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), self->gstyle_files_filter);
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), self->gpl_files_filter);
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), self->builder_files_filter);
+}
+
+static GtkWidget *
+create_file_load_dialog (GbColorPickerPrefs   *self)
+{
+  GtkWindow *toplevel;
+  GtkWidget *dialog;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (self->panel != NULL && GSTYLE_IS_COLOR_PANEL (self->panel));
+
+  toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self->panel)));
+  dialog = gtk_file_chooser_dialog_new (_("Load palette"),
+                                        toplevel,
+                                        GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        _("Open"),
+                                        GTK_RESPONSE_OK,
+                                        NULL);
+
+  gtk_dialog_add_button (GTK_DIALOG (dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
+  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+  file_dialog_add_filters (self, dialog);
+  palette_dialog_add_preview (self, dialog);
+
+  return dialog;
+}
+
+static GtkWidget *
+create_file_save_dialog (GbColorPickerPrefs   *self,
+                         GstylePalette        *palette)
+{
+  GtkWindow *toplevel;
+  GtkWidget *dialog;
+  g_autofree gchar *name = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (self->panel != NULL && GSTYLE_IS_COLOR_PANEL (self->panel));
+
+  toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self->panel)));
+  dialog = gtk_file_chooser_dialog_new (_("Save palette"),
+                                        toplevel,
+                                        GTK_FILE_CHOOSER_ACTION_SAVE,
+                                        _("Save"),
+                                        GTK_RESPONSE_OK,
+                                        NULL);
+
+  gtk_dialog_add_button (GTK_DIALOG (dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
+  gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+  file_dialog_add_filters (self, dialog);
+  palette_dialog_add_preview (self, dialog);
+
+  name = g_strdup_printf ("%s.xml", gstyle_palette_get_name (palette));
+  gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), name);
+  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+
+  return dialog;
+}
+
+static void
+palette_load_dialog_cb (GbColorPickerPrefs *self,
+                        gint                response_id,
+                        GtkDialog          *dialog)
+{
+  g_autoptr (GFile) file = NULL;
+  GstylePalette *palette;
+  const gchar *palette_name;
+  GError *error = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GTK_IS_DIALOG (dialog));
+
+  if (response_id == GTK_RESPONSE_OK)
+    {
+      /* TODO: check for file, not dir */
+      file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+      if (file != NULL)
+        {
+          palette = gstyle_palette_new_from_file (file, NULL, &error);
+          if (palette == NULL)
+            {
+              g_warning ("Can't load the palette: %s", error->message);
+              g_error_free (error);
+            }
+          else
+            {
+              if (!gstyle_palette_widget_add (self->palette_widget, palette))
+                {
+                  palette_name = gstyle_palette_get_name (palette);
+                  g_warning ("The palette named '%s' already exist in the list", palette_name);
+                }
+              else
+                gstyle_palette_widget_show_palette (self->palette_widget, palette);
+
+              g_object_unref (palette);
+            }
+        }
+    }
+
+  gstyle_palette_widget_remove_all (GSTYLE_PALETTE_WIDGET (self->preview_palette_widget));
+  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), NULL);
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+load_palette_button_clicked_cb (GbColorPickerPrefs *self,
+                                GtkButton          *button)
+{
+  GtkWidget *dialog;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  dialog = create_file_load_dialog (self);
+  g_signal_connect_object (dialog, "response", G_CALLBACK (palette_load_dialog_cb), self, G_CONNECT_SWAPPED);
+  gtk_widget_show (dialog);
+}
+
+static void
+palette_save_dialog_cb (GbColorPickerPrefs *self,
+                        gint                response_id,
+                        GtkDialog          *dialog)
+{
+  GstylePalette *selected_palette;
+  g_autoptr (GFile) file = NULL;
+  const gchar *palette_name;
+  GError *error = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GTK_IS_DIALOG (dialog));
+
+  if (response_id == GTK_RESPONSE_OK)
+    {
+      selected_palette = gstyle_palette_widget_get_selected_palette (self->palette_widget);
+      file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
+      if (file != NULL)
+        if (!gstyle_palette_save_to_xml (selected_palette, file, &error))
+        {
+          palette_name = gstyle_palette_get_name (selected_palette);
+          g_warning ("Can't save the palette anmed '%s': %s",
+                     palette_name,
+                     error->message);
+
+          g_error_free (error);
+        }
+    }
+
+  gstyle_palette_widget_remove_all (GSTYLE_PALETTE_WIDGET (self->preview_palette_widget));
+  gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (dialog), NULL);
+  gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+save_palette_button_clicked_cb (GbColorPickerPrefs *self,
+                                GtkButton          *button)
+{
+  GtkWidget *dialog;
+  GstylePalette *selected_palette;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GTK_IS_BUTTON (button));
+
+  selected_palette = gstyle_palette_widget_get_selected_palette (self->palette_widget);
+  dialog = create_file_save_dialog (self, selected_palette);
+  g_signal_connect_object (dialog, "response", G_CALLBACK (palette_save_dialog_cb), self, G_CONNECT_SWAPPED);
+  gtk_widget_show (dialog);
+}
+
+static void
+gb_color_picker_prefs_row_closed_cb (GbColorPickerPrefs *self,
+                                     const gchar        *palette_id)
+{
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+
+  gstyle_palette_widget_remove_by_id (self->palette_widget, palette_id);
+}
+
+static void
+gb_color_picker_prefs_row_name_changed_cb (GbColorPickerPrefs *self,
+                                           const gchar        *palette_id,
+                                           const gchar        *name)
+{
+  GstylePalette *palette;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+
+  palette = gstyle_palette_widget_get_palette_by_id  (self->palette_widget, palette_id);
+  gstyle_palette_set_name (palette, name);
+  gstyle_color_panel_show_palette (self->panel, palette);
+}
+
+static GtkWidget *
+create_palette_list_item (gpointer item,
+                          gpointer user_data)
+{
+  GbColorPickerPrefs *self = (GbColorPickerPrefs *)user_data;
+  GstylePalette *palette = (GstylePalette *)item;
+  GtkWidget *row;
+  const gchar *name;
+  g_autofree gchar *target;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GSTYLE_IS_PALETTE (palette));
+
+  name = gstyle_palette_get_name (palette);
+  target = g_strdup_printf ("\"%s\"", gstyle_palette_get_id (palette));
+  row = g_object_new (GB_TYPE_COLOR_PICKER_PREFS_PALETTE_ROW,
+                      "visible", TRUE,
+                      "key", "selected-palette-id",
+                      "schema-id", "org.gnome.builder.plugins.color_picker_plugin",
+                      "palette-name", name,
+                      "target", string_to_variant (target),
+                      NULL);
+
+  g_signal_connect_object (row, "closed", G_CALLBACK (gb_color_picker_prefs_row_closed_cb), self, 
G_CONNECT_SWAPPED);
+  g_signal_connect_object (row, "name-changed", G_CALLBACK (gb_color_picker_prefs_row_name_changed_cb), 
self, G_CONNECT_SWAPPED);
+
+  return row;
+}
+
+GstyleColorPanel *
+gb_color_picker_prefs_get_panel (GbColorPickerPrefs *self)
+{
+  g_return_val_if_fail (GB_IS_COLOR_PICKER_PREFS (self), NULL);
+
+  return self->panel;
+}
+
+static void
+gb_color_picker_prefs_bind_settings (GbColorPickerPrefs *self)
+{
+  g_return_if_fail (GB_IS_COLOR_PICKER_PREFS (self));
+
+  g_settings_bind (self->plugin_settings,"selected-palette-id",
+                   self->palette_widget, "selected-palette-id",
+                   G_SETTINGS_BIND_DEFAULT);
+
+  g_settings_bind (self->components_settings,"hsv-visible",
+                   self->panel, "hsv-visible",
+                   G_SETTINGS_BIND_GET);
+
+  g_settings_bind (self->components_settings,"lab-visible",
+                   self->panel, "lab-visible",
+                   G_SETTINGS_BIND_GET);
+
+  g_settings_bind (self->components_settings,"rgb-visible",
+                   self->panel, "rgb-visible",
+                   G_SETTINGS_BIND_GET);
+
+  g_settings_bind (self->components_settings,"rgb-unit",
+                   self->panel, "rgb-unit",
+                   G_SETTINGS_BIND_GET);
+
+  g_settings_bind (self->plugin_settings,"strings-visible",
+                   self->panel, "strings-visible",
+                   G_SETTINGS_BIND_GET);
+}
+
+static void
+gb_color_picker_prefs_unbind_settings (GbColorPickerPrefs *self)
+{
+  g_return_if_fail (GB_IS_COLOR_PICKER_PREFS (self));
+
+  g_settings_unbind (self->palette_widget, "selected-palette-id");
+  g_settings_unbind (self->panel, "hsv-visible");
+  g_settings_unbind (self->panel, "lab-visible");
+  g_settings_unbind (self->panel, "rgb-visible");
+  g_settings_unbind (self->panel, "rgb-unit");
+  g_settings_unbind (self->panel, "string-visible");
+}
+
+void
+gb_color_picker_prefs_set_panel (GbColorPickerPrefs *self,
+                                 GstyleColorPanel   *panel)
+{
+  g_return_if_fail (GB_IS_COLOR_PICKER_PREFS (self));
+  g_return_if_fail (panel == NULL || GSTYLE_IS_COLOR_PANEL (panel));
+
+  if (self->panel != panel)
+    {
+      if (self->panel)
+        {
+          gb_color_picker_prefs_unbind_settings (self);
+          gstyle_color_panel_set_prefs_pages (self->panel, NULL, NULL, NULL, NULL);
+          gtk_list_box_bind_model (GTK_LIST_BOX (self->palettes_listbox), NULL, NULL, NULL, NULL);
+          self->panel = NULL;
+          self->palette_widget = NULL;
+        }
+
+      self->panel = panel;
+      if (panel != NULL && GSTYLE_IS_COLOR_PANEL (panel))
+        {
+          self->palette_widget = gstyle_color_panel_get_palette_widget (self->panel);
+          self->palettes_store = gstyle_palette_widget_get_store (self->palette_widget);
+          gtk_list_box_bind_model (GTK_LIST_BOX (self->palettes_listbox),
+                                   G_LIST_MODEL (self->palettes_store),
+                                   create_palette_list_item, self, NULL);
+
+          gstyle_color_panel_set_prefs_pages (panel,
+                                              gb_color_picker_prefs_get_page (self, 
GSTYLE_COLOR_PANEL_PREFS_COMPONENTS),
+                                              gb_color_picker_prefs_get_page (self, 
GSTYLE_COLOR_PANEL_PREFS_COLOR_STRINGS),
+                                              gb_color_picker_prefs_get_page (self, 
GSTYLE_COLOR_PANEL_PREFS_PALETTES),
+                                              gb_color_picker_prefs_get_page (self, 
GSTYLE_COLOR_PANEL_PREFS_PALETTES_LIST));
+
+          gb_color_picker_prefs_bind_settings (self);
+        }
+
+      g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_PANEL]);
+    }
+}
+
+static void
+gb_color_picker_prefs_palette_added_cb (GbColorPickerPrefs            *self,
+                                        GbColorPickerPrefsPaletteList *palette_box)
+{
+  GstylePalette *palette;
+
+  g_assert (GB_IS_COLOR_PICKER_PREFS (self));
+  g_assert (GB_IS_COLOR_PICKER_PREFS_PALETTE_LIST (palette_box));
+
+  palette = gstyle_palette_new ();
+  gstyle_palette_widget_add (self->palette_widget, palette);
+  g_object_unref (palette);
+}
+
+GbColorPickerPrefs *
+gb_color_picker_prefs_new (void)
+{
+  return g_object_new (GB_TYPE_COLOR_PICKER_PREFS, NULL);
+}
+
+static void
+gb_color_picker_prefs_get_property (GObject    *object,
+                                    guint       prop_id,
+                                    GValue     *value,
+                                    GParamSpec *pspec)
+{
+  GbColorPickerPrefs *self = GB_COLOR_PICKER_PREFS (object);
+
+  switch (prop_id)
+    {
+    case PROP_PANEL:
+      g_value_set_object (value, gb_color_picker_prefs_get_panel (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_color_picker_prefs_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  GbColorPickerPrefs *self = GB_COLOR_PICKER_PREFS (object);
+
+  switch (prop_id)
+    {
+    case PROP_PANEL:
+      gb_color_picker_prefs_set_panel (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gb_color_picker_prefs_finalize (GObject *object)
+{
+  GbColorPickerPrefs *self = (GbColorPickerPrefs *)object;
+
+  gb_color_picker_prefs_set_panel (self, NULL);
+
+  g_clear_object (&self->components_page);
+  g_clear_object (&self->color_strings_page);
+  g_clear_object (&self->palettes_page);
+  g_clear_object (&self->palettes_list_page);
+
+  g_clear_object (&self->all_files_filter);
+  g_clear_object (&self->gstyle_files_filter);
+  g_clear_object (&self->gpl_files_filter);
+  g_clear_object (&self->builder_files_filter);
+
+  g_clear_object (&self->preview);
+  g_clear_object (&self->plugin_settings);
+  g_clear_object (&self->components_settings);
+
+  G_OBJECT_CLASS (gb_color_picker_prefs_parent_class)->finalize (object);
+}
+
+static void
+gb_color_picker_prefs_class_init (GbColorPickerPrefsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gb_color_picker_prefs_finalize;
+  object_class->set_property = gb_color_picker_prefs_set_property;
+  object_class->get_property = gb_color_picker_prefs_get_property;
+
+  properties [PROP_PANEL] =
+    g_param_spec_object ("panel",
+                         "panel",
+                         "Color panel",
+                         GSTYLE_TYPE_COLOR_PANEL,
+                         (G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_properties (object_class, N_PROPS, properties);
+}
+
+static void
+gb_color_picker_prefs_init (GbColorPickerPrefs *self)
+{
+  GtkBuilder *builder;
+  GtkWidget *palettes_placeholder;
+
+  g_type_ensure (GB_TYPE_COLOR_PICKER_PREFS_LIST);
+  g_type_ensure (GB_TYPE_COLOR_PICKER_PREFS_PALETTE_LIST);
+
+  builder = gtk_builder_new_from_resource 
("/org/gnome/builder/plugins/color-picker-plugin/gtk/color-picker-prefs.ui");
+
+  self->palettes_box = GB_COLOR_PICKER_PREFS_PALETTE_LIST (gtk_builder_get_object (builder, "palettes_box"));
+  palettes_placeholder = GTK_WIDGET (gtk_builder_get_object (builder, "palettes_placeholder"));
+  self->palettes_listbox = gb_color_picker_prefs_palette_list_get_list_box (self->palettes_box);
+  gtk_list_box_set_placeholder (self->palettes_listbox, palettes_placeholder);
+
+  g_signal_connect_object (self->palettes_box, "added",
+                           G_CALLBACK (gb_color_picker_prefs_palette_added_cb),
+                           self, G_CONNECT_SWAPPED);
+
+  self->load_palette_button = GTK_WIDGET (gtk_builder_get_object (builder, "load_palette_button"));
+  self->save_palette_button = GTK_WIDGET (gtk_builder_get_object (builder, "save_palette_button"));
+
+  self->all_files_filter = g_object_ref_sink (gtk_file_filter_new ());
+  gtk_file_filter_set_name (self->all_files_filter, _("All files"));
+  gtk_file_filter_add_pattern (self->all_files_filter, "*.*");
+
+  self->gstyle_files_filter = g_object_ref_sink (gtk_file_filter_new ());
+  gtk_file_filter_set_name (self->gstyle_files_filter, _("All supported palettes formats"));
+  gtk_file_filter_add_pattern (self->gstyle_files_filter, "*.gpl");
+  gtk_file_filter_add_pattern (self->gstyle_files_filter, "*.xml");
+
+  self->gpl_files_filter = g_object_ref_sink (gtk_file_filter_new ());
+  gtk_file_filter_set_name (self->gpl_files_filter, _("Gimp palette"));
+  gtk_file_filter_add_pattern (self->gpl_files_filter, "*.gpl");
+
+  self->builder_files_filter = g_object_ref_sink (gtk_file_filter_new ());
+  gtk_file_filter_set_name (self->builder_files_filter, _("Gnome-builder palette"));
+  gtk_file_filter_add_pattern (self->builder_files_filter, "*.xml");
+
+  g_signal_connect_swapped (self->load_palette_button, "clicked", G_CALLBACK 
(load_palette_button_clicked_cb), self);
+  g_signal_connect_swapped (self->save_palette_button, "clicked", G_CALLBACK 
(save_palette_button_clicked_cb), self);
+
+  self->components_page = GTK_WIDGET (gtk_builder_get_object (builder, "components_page"));
+  g_object_ref_sink (self->components_page);
+  self->color_strings_page = GTK_WIDGET (gtk_builder_get_object (builder, "colorstrings_page"));
+  g_object_ref_sink (self->color_strings_page);
+  self->palettes_page = GTK_WIDGET (gtk_builder_get_object (builder, "palettes_page"));
+  g_object_ref_sink (self->palettes_page);
+  self->palettes_list_page = GTK_WIDGET (gtk_builder_get_object (builder, "paletteslist_page"));
+  g_object_ref_sink (self->palettes_list_page);
+
+  g_object_unref (builder);
+
+  builder = gtk_builder_new_from_resource 
("/org/gnome/builder/plugins/color-picker-plugin/gtk/color-picker-preview.ui");
+  self->preview = GTK_WIDGET (gtk_builder_get_object (builder, "preview"));
+  g_object_ref_sink (self->preview);
+  self->preview_palette_widget = GTK_WIDGET (gtk_builder_get_object (builder, "preview_palette_widget"));
+  self->preview_title = GTK_WIDGET (gtk_builder_get_object (builder, "preview_title"));
+
+  self->preview_placeholder = GTK_WIDGET (gtk_builder_get_object (builder, "preview_placeholder"));
+  gstyle_palette_widget_set_placeholder (GSTYLE_PALETTE_WIDGET (self->preview_palette_widget), 
self->preview_placeholder);
+
+  g_object_unref (builder);
+
+  self->plugin_settings = g_settings_new ("org.gnome.builder.plugins.color_picker_plugin");
+  self->components_settings = g_settings_new ("org.gnome.builder.plugins.color_picker_plugin.components");
+}
diff --git a/plugins/color-picker/gb-color-picker-prefs.h b/plugins/color-picker/gb-color-picker-prefs.h
new file mode 100644
index 0000000..67df1f6
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-prefs.h
@@ -0,0 +1,44 @@
+/* gb-color-picker-prefs.h
+ *
+ * Copyright (C) 2016 Sebastien Lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_PREFS_H
+#define GB_COLOR_PICKER_PREFS_H
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include "gstyle-color-panel.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_COLOR_PICKER_PREFS (gb_color_picker_prefs_get_type())
+
+G_DECLARE_FINAL_TYPE (GbColorPickerPrefs, gb_color_picker_prefs, GB, COLOR_PICKER_PREFS, GObject)
+
+GbColorPickerPrefs    *gb_color_picker_prefs_new                (void);
+
+GtkWidget             *gb_color_picker_prefs_get_page           (GbColorPickerPrefs     *self,
+                                                                 GstyleColorPanelPrefs   prefs_type);
+
+GstyleColorPanel      *gb_color_picker_prefs_get_panel          (GbColorPickerPrefs     *self);
+void                   gb_color_picker_prefs_set_panel          (GbColorPickerPrefs     *self,
+                                                                 GstyleColorPanel       *panel);
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_PREFS_H */
diff --git a/plugins/color-picker/gb-color-picker-private.h b/plugins/color-picker/gb-color-picker-private.h
new file mode 100644
index 0000000..e086ffb
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-private.h
@@ -0,0 +1,31 @@
+/* gb-color-picker-private.h
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_PRIVATE_H
+#define GB_COLOR_PICKER_PRIVATE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define COLOR_TAG_PREFIX "cp-gb-"
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_PRIVATE_H */
+
diff --git a/plugins/color-picker/gb-color-picker-workbench-addin.c 
b/plugins/color-picker/gb-color-picker-workbench-addin.c
new file mode 100644
index 0000000..4543f44
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-workbench-addin.c
@@ -0,0 +1,533 @@
+/* gb-color-picker-workbench_addin.c
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtksourceview/gtksource.h>
+#include <ide.h>
+
+#include "gstyle-color.h"
+#include "gstyle-color-panel.h"
+#include "gstyle-palette.h"
+#include "gstyle-palette-widget.h"
+
+#include "gb-color-picker-document-monitor.h"
+#include "gb-color-picker-prefs.h"
+
+#include "gb-color-picker-workbench-addin.h"
+
+typedef struct __ViewState
+{
+  gboolean                      state;
+  GbColorPickerDocumentMonitor *monitor;
+} ViewState;
+
+struct _GbColorPickerWorkbenchAddin
+{
+  GObject                parent_instance;
+
+  GHashTable            *views;
+  IdeWorkbench          *workbench;
+  IdeEditorPerspective  *editor;
+  GtkWidget             *active_view;
+  GtkWidget             *dock;
+  GtkWidget             *color_panel;
+  GbColorPickerPrefs    *prefs;
+
+  guint                  dock_count;
+  guint                  monitor_count;
+};
+
+static void workbench_addin_iface_init (IdeWorkbenchAddinInterface *iface);
+
+G_DEFINE_TYPE_EXTENDED (GbColorPickerWorkbenchAddin, gb_color_picker_workbench_addin, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (IDE_TYPE_WORKBENCH_ADDIN, workbench_addin_iface_init))
+
+static GstylePalette *
+add_palette (GbColorPickerWorkbenchAddin *self,
+             GstylePaletteWidget         *palette_widget,
+             const gchar                 *uri)
+{
+  GstylePalette *palette;
+  g_autoptr (GFile) file = NULL;
+  GError *error = NULL;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (GSTYLE_PALETTE_WIDGET (palette_widget));
+  g_assert (!ide_str_empty0 (uri));
+
+  file = g_file_new_for_uri (uri);
+  palette = gstyle_palette_new_from_file (file, NULL, &error);
+  if (palette == NULL)
+    {
+      g_assert (error != NULL);
+
+      g_warning ("Unable to load the palette: %s\n", error->message);
+      g_error_free (error);
+
+      return NULL;
+    }
+
+  gstyle_palette_widget_add (palette_widget, palette);
+  g_object_unref (palette);
+
+  return palette;
+}
+
+static void
+init_palettes (GbColorPickerWorkbenchAddin *self)
+{
+  GstylePaletteWidget *palette_widget;
+  GstylePalette *palette;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+
+  palette_widget = gstyle_color_panel_get_palette_widget (GSTYLE_COLOR_PANEL (self->color_panel));
+  add_palette (self, palette_widget, 
"resource:///org/gnome/builder/plugins/color-picker-plugin/data/basic.xml");
+  palette = add_palette (self, palette_widget, 
"resource:///org/gnome/builder/plugins/color-picker-plugin/data/svg.gpl");
+
+  gstyle_color_panel_show_palette (GSTYLE_COLOR_PANEL (self->color_panel), palette);
+}
+
+static void
+set_menu_action_state (GbColorPickerWorkbenchAddin *self,
+                       IdeEditorView               *view,
+                       gboolean                     state)
+{
+  GActionGroup *group;
+  GAction *menu_action;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  group = gtk_widget_get_action_group (GTK_WIDGET (view), "view");
+  if (group != NULL)
+    {
+      menu_action = g_action_map_lookup_action(G_ACTION_MAP (group), "activate-color-picker");
+     if (menu_action != NULL)
+       g_action_change_state (menu_action, g_variant_new_boolean (state));
+    }
+}
+
+static gboolean
+get_menu_action_state (GbColorPickerWorkbenchAddin *self,
+                       IdeEditorView               *view)
+{
+  GActionGroup *group;
+  GAction *menu_action;
+  gboolean state = FALSE;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  group = gtk_widget_get_action_group (GTK_WIDGET (view), "view");
+  if (group != NULL)
+    {
+      menu_action = g_action_map_lookup_action(G_ACTION_MAP (group), "activate-color-picker");
+     if (menu_action != NULL)
+       state = g_variant_get_boolean (g_action_get_state (menu_action));
+    }
+
+  return state;
+}
+
+static GbColorPickerDocumentMonitor *
+get_view_monitor (GbColorPickerWorkbenchAddin *self,
+                  IdeEditorView               *view)
+{
+  GbColorPickerDocumentMonitor *monitor;
+  IdeBuffer *buffer;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  buffer = ide_editor_view_get_document (view);
+  if (buffer == NULL)
+    return NULL;
+
+  monitor = g_object_get_data (G_OBJECT (buffer), "monitor");
+  return monitor;
+}
+
+static void
+color_panel_rgba_set_cb (GbColorPickerWorkbenchAddin *self,
+                         GParamSpec                  *prop)
+{
+  GbColorPickerDocumentMonitor *monitor;
+  g_autoptr (GstyleColor) color = NULL;
+  GdkRGBA rgba;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+
+  gstyle_color_panel_get_rgba (GSTYLE_COLOR_PANEL (self->color_panel), &rgba);
+  color = gstyle_color_new_from_rgba (NULL, GSTYLE_COLOR_KIND_RGB_HEX6, &rgba);
+
+  monitor = get_view_monitor (self, IDE_EDITOR_VIEW (self->active_view));
+  if (monitor != NULL)
+    gb_color_picker_document_monitor_set_color_tag_at_cursor (monitor, color);
+}
+
+static gboolean
+init_dock (GbColorPickerWorkbenchAddin *self)
+{
+  GtkWidget *panel;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+
+  self->dock = g_object_new (PNL_TYPE_DOCK_WIDGET,
+                             "title", _("Color Picker"),
+                             "expand", TRUE,
+                             "visible", TRUE,
+                             NULL);
+  self->color_panel = g_object_new (GSTYLE_TYPE_COLOR_PANEL,
+                                    "visible", TRUE,
+                                    NULL);
+
+  self->prefs = g_object_new (GB_TYPE_COLOR_PICKER_PREFS,
+                              "panel", self->color_panel,
+                              NULL);
+
+  init_palettes (self);
+
+  panel = (pnl_dock_bin_get_right_edge (PNL_DOCK_BIN (self->editor)));
+  gtk_container_add (GTK_CONTAINER (panel), GTK_WIDGET (self->dock));
+  gtk_container_add (GTK_CONTAINER (self->dock), self->color_panel);
+
+  g_signal_connect_object (self->color_panel,
+                           "notify::rgba",
+                           G_CALLBACK (color_panel_rgba_set_cb),
+                           self,
+                           G_CONNECT_SWAPPED);
+
+  self->dock_count = 1;
+  return TRUE;
+}
+
+static gboolean
+remove_dock (GbColorPickerWorkbenchAddin *self)
+{
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+
+  self->dock_count = 0;
+  self->color_panel = NULL;
+  if (self->dock == NULL)
+    return FALSE;
+
+  gb_color_picker_prefs_set_panel (self->prefs, NULL);
+  g_object_unref (self->prefs);
+  gtk_widget_destroy (self->dock);
+  self->dock = NULL;
+
+  return TRUE;
+}
+
+static void
+monitor_color_found_cb (GbColorPickerWorkbenchAddin  *self,
+                        GstyleColor                  *color,
+                        GbColorPickerDocumentMonitor *monitor)
+{
+  IdeBuffer *active_buffer;
+  GdkRGBA rgba;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (GB_IS_COLOR_PICKER_DOCUMENT_MONITOR (monitor));
+  g_assert (GSTYLE_IS_COLOR (color));
+
+  if (self->active_view == NULL)
+    return;
+
+  active_buffer = ide_editor_view_get_document (IDE_EDITOR_VIEW (self->active_view));
+  if (active_buffer != NULL && self->dock != NULL)
+    {
+      gstyle_color_fill_rgba (color, &rgba);
+
+      g_signal_handlers_block_by_func (self->color_panel, color_panel_rgba_set_cb, self);
+      gstyle_color_panel_set_rgba (GSTYLE_COLOR_PANEL (self->color_panel), &rgba);
+      g_signal_handlers_unblock_by_func (self->color_panel, color_panel_rgba_set_cb, self);
+    }
+}
+
+static void
+view_clear_cb (GtkWidget                   *widget,
+               GbColorPickerWorkbenchAddin *self)
+{
+  IdeEditorView *view;
+  GActionGroup *group;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (widget));
+
+  view = IDE_EDITOR_VIEW (widget);
+
+  group = gtk_widget_get_action_group (widget, "view");
+  if (group != NULL)
+    g_action_map_remove_action (G_ACTION_MAP (group), "activate-color-picker");
+
+  g_hash_table_remove (self->views, view);
+}
+
+static void
+view_clear (GbColorPickerWorkbenchAddin *self,
+            IdeEditorView               *view,
+            gboolean                     remove_color)
+{
+  GbColorPickerDocumentMonitor *monitor;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  monitor = get_view_monitor (self, view);
+  if (monitor != NULL)
+    {
+      if (remove_color)
+        gb_color_picker_document_monitor_uncolorize (monitor, NULL, NULL);
+
+    self->monitor_count -= 1;
+    if (self->monitor_count == 0)
+      g_object_unref (monitor);
+    }
+}
+
+static void
+view_remove_dock (GbColorPickerWorkbenchAddin *self,
+                  IdeEditorView               *view)
+{
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  if (self->dock == NULL)
+    return;
+
+  if (--self->dock_count <= 0)
+    remove_dock (self);
+  else
+    {
+      //gtk_widget_set_sensitive (GTK_WIDGET (self->dock), FALSE);
+      gtk_widget_set_opacity (GTK_WIDGET (self->dock), 0.2);
+    }
+}
+
+static void
+activate_color_picker_action_cb (GbColorPickerWorkbenchAddin *self,
+                                 GVariant                    *param,
+                                 GSimpleAction               *menu_action)
+{
+  GbColorPickerDocumentMonitor *monitor;
+  IdeEditorView *view;
+  gboolean state;
+  IdeBuffer *buffer;
+  ViewState *view_state;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (G_IS_SIMPLE_ACTION (menu_action));
+
+  view = g_object_get_data (G_OBJECT (menu_action), "view");
+  if (view == NULL || !IDE_IS_EDITOR_VIEW (view))
+    return;
+
+  state = get_menu_action_state (self, view);
+  if (!state)
+    {
+      if (self->dock != NULL)
+        {
+          ++self->dock_count;
+          gtk_widget_set_sensitive (GTK_WIDGET (self->dock), TRUE);
+        }
+      else
+        init_dock (self);
+
+      buffer = ide_editor_view_get_document (view);
+      monitor = g_object_get_data (G_OBJECT (buffer), "monitor");
+      if (monitor == NULL)
+        {
+          monitor = gb_color_picker_document_monitor_new (buffer);
+          g_object_set_data (G_OBJECT (buffer), "monitor", monitor);
+          g_signal_connect_object (monitor,
+                                   "color-found",
+                                   G_CALLBACK (monitor_color_found_cb), self,
+                                   G_CONNECT_SWAPPED);
+        }
+      else
+        g_object_ref (monitor);
+
+      ide_workbench_focus (self->workbench, GTK_WIDGET (self->dock));
+      gb_color_picker_document_monitor_colorize (monitor, NULL, NULL);
+    }
+  else
+    {
+      view_clear (self, view, TRUE);
+      view_remove_dock (self, view);
+    }
+
+  view_state = g_hash_table_lookup (self->views, view);
+  view_state->state = !state;
+  set_menu_action_state (self, view, !state);
+
+  if (self->dock != NULL)
+    gtk_widget_set_opacity (GTK_WIDGET (self->dock), !state ? 1 : 0.2);
+}
+
+static void
+setup_view_cb (GtkWidget                   *widget,
+               GbColorPickerWorkbenchAddin *self)
+{
+  IdeEditorView *view = (IdeEditorView *)widget;
+  GActionGroup *group;
+  GSimpleAction *menu_action;
+  ViewState *view_state;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  view_state = g_new0 (ViewState, 1);
+  view_state->state = FALSE;
+  g_hash_table_insert (self->views, view, view_state);
+
+  menu_action = g_simple_action_new_stateful ("activate-color-picker",
+                                              NULL,
+                                              g_variant_new_boolean(FALSE));
+
+  group = gtk_widget_get_action_group (widget, "view");
+  g_object_set_data (G_OBJECT (menu_action), "view", view);
+
+  g_action_map_add_action (G_ACTION_MAP (group), G_ACTION (menu_action));
+  set_menu_action_state (self, view, FALSE);
+  g_signal_connect_swapped (menu_action,
+                            "activate",
+                            G_CALLBACK (activate_color_picker_action_cb),
+                            self);
+}
+
+static void
+view_added_cb (GbColorPickerWorkbenchAddin *self,
+               GtkWidget                   *widget)
+{
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+
+  if (!IDE_IS_EDITOR_VIEW (widget))
+    return;
+
+  setup_view_cb (widget, self);
+}
+
+static void
+view_removed_cb (GbColorPickerWorkbenchAddin *self,
+                 GtkWidget                   *widget)
+{
+  IdeEditorView *view = (IdeEditorView *)widget;
+  ViewState *view_state;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+  g_assert (IDE_IS_EDITOR_VIEW (view));
+
+  if (!IDE_IS_EDITOR_VIEW (widget))
+    return;
+
+  view_state = g_hash_table_lookup (self->views, view);
+  if (view != NULL && view_state->state)
+    {
+      view_clear (self, view, FALSE);
+      view_remove_dock (self, view);
+    }
+
+  g_hash_table_remove (self->views, view);
+}
+
+static void
+active_view_changed_cb (GbColorPickerWorkbenchAddin *self,
+                        GParamSpec                  *prop)
+{
+  gboolean state;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (self));
+
+  self->active_view = ide_layout_get_active_view (IDE_LAYOUT (self->editor));
+  if (self->active_view != NULL && IDE_IS_EDITOR_VIEW (self->active_view))
+    {
+      state = get_menu_action_state (self, IDE_EDITOR_VIEW (self->active_view));
+      if (self->dock != NULL && self->dock_count > 0)
+        {
+          gtk_widget_set_opacity (GTK_WIDGET (self->dock), state ? 1 : 0.2);
+          //gtk_widget_set_sensitive (GTK_WIDGET (self->dock), state);
+        }
+    }
+}
+
+static void
+gb_color_picker_workbench_addin_load (IdeWorkbenchAddin *addin,
+                                      IdeWorkbench      *workbench)
+{
+  GbColorPickerWorkbenchAddin *self = (GbColorPickerWorkbenchAddin *)addin;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (addin));
+  g_assert (IDE_IS_WORKBENCH (workbench));
+
+  ide_set_weak_pointer (&self->workbench, workbench);
+  self->editor = IDE_EDITOR_PERSPECTIVE (ide_workbench_get_perspective_by_name (workbench, "editor"));
+
+  ide_perspective_views_foreach (IDE_PERSPECTIVE (self->editor), (GtkCallback)setup_view_cb, self);
+  self->active_view = ide_layout_get_active_view (IDE_LAYOUT (self->editor));
+
+  g_signal_connect_swapped (self->editor,
+                            "view-added",
+                            G_CALLBACK (view_added_cb),
+                            self);
+  g_signal_connect_swapped (self->editor,
+                            "view-removed",
+                            G_CALLBACK (view_removed_cb),
+                            self);
+  g_signal_connect_swapped (IDE_LAYOUT (self->editor),
+                            "notify::active-view",
+                            G_CALLBACK (active_view_changed_cb),
+                            self);
+}
+
+static void
+gb_color_picker_workbench_addin_unload (IdeWorkbenchAddin *addin,
+                                        IdeWorkbench       *workbench)
+{
+  GbColorPickerWorkbenchAddin *self = (GbColorPickerWorkbenchAddin *)addin;
+
+  g_assert (GB_IS_COLOR_PICKER_WORKBENCH_ADDIN (addin));
+  g_assert (IDE_IS_WORKBENCH (workbench));
+
+  ide_perspective_views_foreach (IDE_PERSPECTIVE (self->editor), (GtkCallback)view_clear_cb, self);
+
+  remove_dock (self);
+  g_hash_table_unref (self->views);
+
+  ide_clear_weak_pointer (&self->workbench);
+}
+
+static void
+gb_color_picker_workbench_addin_class_init (GbColorPickerWorkbenchAddinClass *klass)
+{
+}
+
+static void
+gb_color_picker_workbench_addin_init (GbColorPickerWorkbenchAddin *self)
+{
+  self->views = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+}
+
+static void
+workbench_addin_iface_init (IdeWorkbenchAddinInterface *iface)
+{
+  iface->load = gb_color_picker_workbench_addin_load;
+  iface->unload = gb_color_picker_workbench_addin_unload;
+}
diff --git a/plugins/color-picker/gb-color-picker-workbench-addin.h 
b/plugins/color-picker/gb-color-picker-workbench-addin.h
new file mode 100644
index 0000000..8c2b3f2
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker-workbench-addin.h
@@ -0,0 +1,32 @@
+/* gb-color-picker-workbench-addin.h
+ *
+ * Copyright (C) 2016 sebastien lafargue <slafargue gnome org>
+ *
+ * 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_COLOR_PICKER_WORKBENCH_ADDIN_H
+#define GB_COLOR_PICKER_WORKBENCH_ADDIN_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_COLOR_PICKER_WORKBENCH_ADDIN (gb_color_picker_workbench_addin_get_type())
+
+G_DECLARE_FINAL_TYPE (GbColorPickerWorkbenchAddin, gb_color_picker_workbench_addin, GB, 
COLOR_PICKER_WORKBENCH_ADDIN, GObject)
+
+G_END_DECLS
+
+#endif /* GB_COLOR_PICKER_WORKBENCH_ADDIN_H */
diff --git a/plugins/color-picker/gb-color-picker.gresource.xml 
b/plugins/color-picker/gb-color-picker.gresource.xml
new file mode 100644
index 0000000..a4aff9b
--- /dev/null
+++ b/plugins/color-picker/gb-color-picker.gresource.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gnome/builder/plugins/color-picker-plugin">
+    <file>theme/Adwaita.css</file>
+    <file>theme/Adwaita-dark.css</file>
+    <file>theme/Adwaita-shared.css</file>
+
+    <file>gtk/color-picker.ui</file>
+    <file>gtk/color-picker-prefs.ui</file>
+    <file>gtk/color-picker-prefs-palette-list.ui</file>
+    <file>gtk/color-picker-preview.ui</file>
+    <file>gtk/color-picker-palette-row.ui</file>
+    <file>gtk/menus.ui</file>
+
+    <file>data/basic.xml</file>
+    <file>data/svg.gpl</file>
+
+    <file compressed="true" 
alias="icons/scalable/actions/builder-colorpicker-load-palette.svg">icons/palette/load-palette.svg</file>
+    <file compressed="true" 
alias="icons/scalable/actions/builder-colorpicker-save-palette.svg">icons/palette/save-palette.svg</file>
+    <file compressed="true" 
alias="icons/scalable/actions/builder-colorpicker-viewmode-list.svg">icons/viewmode/viewmode-list.svg</file>
+    <file compressed="true" 
alias="icons/scalable/actions/builder-colorpicker-viewmode-swatchs.svg">icons/viewmode/viewmode-swatchs.svg</file>
+  </gresource>
+</gresources>
diff --git a/plugins/color-picker/gsettings/org.gnome.builder.plugins.color_picker_plugin.gschema.xml 
b/plugins/color-picker/gsettings/org.gnome.builder.plugins.color_picker_plugin.gschema.xml
new file mode 100644
index 0000000..8d6f127
--- /dev/null
+++ b/plugins/color-picker/gsettings/org.gnome.builder.plugins.color_picker_plugin.gschema.xml
@@ -0,0 +1,44 @@
+<schemalist>
+  <flags id="org.gnome.builder.plugins.color_picker_plugin.StringsVisible">
+    <value nick="hex3" value="1"/>
+    <value nick="hex6" value="2"/>
+    <value nick="rgb" value="4"/>
+    <value nick="rgba" value="8"/>
+    <value nick="hsl" value="16"/>
+    <value nick="hsla" value="32"/>
+  </flags>
+  <schema id="org.gnome.builder.plugins.color_picker_plugin.components" 
path="/org/gnome/builder/plugins/color_picker_plugin/components/" gettext-domain="gnome-builder">
+    <key name="hsv-visible" type="b">
+      <default>true</default>
+      <summary>hsv visibility</summary>
+      <description>If the HSV components are visible.</description>
+    </key>
+    <key name="lab-visible" type="b">
+      <default>true</default>
+      <summary>hsv visibility</summary>
+      <description>If the LAB components are visible.</description>
+    </key>
+    <key name="rgb-visible" type="b">
+      <default>true</default>
+      <summary>hsv visibility</summary>
+      <description>If the RGB components are visible.</description>
+    </key>
+    <key name="rgb-unit" type="s">
+      <default>"percent"</default>
+      <summary>rgb unit</summary>
+      <description>The unit use by RGb component and strings.</description>
+    </key>
+  </schema>
+  <schema id="org.gnome.builder.plugins.color_picker_plugin" 
path="/org/gnome/builder/plugins/color_picker_plugin/" gettext-domain="gnome-builder">
+    <key name="selected-palette-id" type="s">
+      <default>""</default>
+      <summary>Selected palette id</summary>
+      <description>The selected palette id amongst the loaded ones.</description>
+    </key>
+    <key name="strings-visible" flags="org.gnome.builder.plugins.color_picker_plugin.StringsVisible">
+      <default>['hex3', 'hex6', 'rgb', 'rgba', 'hsl', 'hsla']</default>
+      <summary>Color strings visibility</summary>
+      <description>The visible color strings.</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/plugins/color-picker/gtk/color-picker-palette-row.ui 
b/plugins/color-picker/gtk/color-picker-palette-row.ui
new file mode 100644
index 0000000..f29f37a
--- /dev/null
+++ b/plugins/color-picker/gtk/color-picker-palette-row.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.18 -->
+  <template class="GbColorPickerPrefsPaletteRow" parent="IdePreferencesBin">
+    <property name="vexpand">false</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">true</property>
+        <property name="spacing">6</property>
+        <child>
+          <object class="GtkEventBox" id="event_box">
+            <property name="visible">true</property>
+            <property name="visible-window">false</property>
+            <property name="above-child">true</property>"
+            <child>
+              <object class="GtkBox">
+                <property name="spacing">6</property>
+                <property name="visible">true</property>
+                <child>
+                  <object class="GtkEntry" id="palette_name">
+                    <property name="visible">true</property>
+                    <property name="activates-default">false</property>
+                    <property name="hexpand">true</property>
+                    <property name="xalign">0.0</property>
+                    <property name="placeholder-text" translatable="yes">No name</property>
+                    <style>
+                      <class name="flat"/>
+                    </style>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image">
+                    <property name="icon-name">object-select-symbolic</property>
+    -               <property name="icon-size">4</property>
+    -               <property name="valign">center</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkButton" id="button">
+            <property name="visible">true</property>
+            <property name="hexpand">true</property>
+            <property name="halign">end</property>
+            <style>
+              <class name="flat"/>
+            </style>
+            <child>
+              <object class="GtkImage">
+                <property name="icon-name">window-close-symbolic</property>
+                <property name="visible">true</property>
+                <property name="valign">center</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/plugins/color-picker/gtk/color-picker-prefs-palette-list.ui 
b/plugins/color-picker/gtk/color-picker-prefs-palette-list.ui
new file mode 100644
index 0000000..c144c40
--- /dev/null
+++ b/plugins/color-picker/gtk/color-picker-prefs-palette-list.ui
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.18 -->
+  <template class="GbColorPickerPrefsPaletteList" parent="GtkBox">
+    <property name="expand">False</property>
+    <property name="visible">true</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkButton" id="plus_button">
+        <property name="visible">true</property>
+        <property name="hexpand">True</property>
+        <style>
+          <class name="flat"/>
+        </style>
+        <child>
+          <object class="GtkImage">
+            <property name="icon-name">list-add-symbolic</property>
+            <property name="visible">true</property>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="visible">True</property>
+        <property name="hscrollbar-policy">never</property>
+        <child>
+          <object class="GtkListBox" id="list_box">
+            <property name="visible">true</property>
+            <property name="selection-mode">none</property>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/plugins/color-picker/gtk/color-picker-prefs.ui b/plugins/color-picker/gtk/color-picker-prefs.ui
new file mode 100644
index 0000000..e42d2c5
--- /dev/null
+++ b/plugins/color-picker/gtk/color-picker-prefs.ui
@@ -0,0 +1,635 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkBox" id="components_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin">6</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Color components</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+        <style>
+          <class name="cp-prefs-title"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">Visibility :</property>
+        <style>
+          <class name="cp-prefs-grouptitle"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">6</property>
+        <property name="margin_bottom">6</property>
+        <property name="label" translatable="yes">Select the colorspaces for which you want to see sliders 
in the panel.</property>
+        <property name="justify">fill</property>
+        <property name="wrap">True</property>
+        <style>
+          <class name="cp-prefs-resume"/>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GbColorPickerPrefsList">
+        <property name="visible">True</property>
+        <child>
+          <object class="IdePreferencesSwitch" id="hsv_switch">
+            <property name="visible">True</property>
+            <property name="key">hsv-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin.components</property>
+            <property name="target">""</property>
+            <property name="title">HSV</property>
+            <property name="subtitle">Hue Saturation Value</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch" id="lab_switch">
+            <property name="visible">True</property>
+            <property name="key">lab-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin.components</property>
+            <property name="target">""</property>
+            <property name="title">L*a*b*</property>
+            <property name="subtitle">CIE L*a*b* 1976</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch" id="rgb_switch">
+            <property name="visible">True</property>
+            <property name="key">rgb-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin.components</property>
+            <property name="target">""</property>
+            <property name="title">RGB</property>
+            <property name="subtitle">Red Green Blue</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">Units :</property>
+        <style>
+          <class name="cp-prefs-grouptitle"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">6</property>
+        <property name="margin_bottom">6</property>
+        <property name="label" translatable="yes">Select the type of unit you want to use for RGB components 
and strings in the panel.</property>
+        <property name="justify">fill</property>
+        <property name="wrap">True</property>
+        <style>
+          <class name="cp-prefs-resume"/>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GbColorPickerPrefsList">
+        <property name="visible">True</property>
+        <child>
+          <object class="IdePreferencesSwitch" id="unit_switch">
+            <property name="visible">True</property>
+            <property name="key">rgb-unit</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin.components</property>
+            <property name="target">"value"</property>
+            <property name="title">Value</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch" id="percent_switch">
+            <property name="visible">True</property>
+            <property name="key">rgb-unit</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin.components</property>
+            <property name="target">"percent"</property>
+            <property name="title">Percent</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkBox" id="colorstrings_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin">6</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Color strings</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+        <style>
+          <class name="cp-prefs-title"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">Visibility :</property>
+        <style>
+          <class name="cp-prefs-grouptitle"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">6</property>
+        <property name="margin_bottom">6</property>
+        <property name="label" translatable="yes">Select the color strings you want to see in the 
panel.</property>
+        <property name="justify">fill</property>
+        <property name="wrap">True</property>
+        <style>
+          <class name="cp-prefs-resume"/>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GbColorPickerPrefsList">
+        <property name="visible">True</property>
+        <child>
+          <object class="IdePreferencesSwitch">
+            <property name="visible">True</property>
+            <property name="key">strings-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin</property>
+            <property name="target">"hex3"</property>
+            <property name="title">HEX3</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch">
+            <property name="visible">True</property>
+            <property name="key">strings-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin</property>
+            <property name="target">"hex6"</property>
+            <property name="title">HEX6</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch">
+            <property name="visible">True</property>
+            <property name="key">strings-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin</property>
+            <property name="target">"rgb"</property>
+            <property name="title">RGB</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch">
+            <property name="visible">True</property>
+            <property name="key">strings-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin</property>
+            <property name="target">"rgba"</property>
+            <property name="title">RGBA</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch">
+            <property name="visible">True</property>
+            <property name="key">strings-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin</property>
+            <property name="target">"hsl"</property>
+            <property name="title">HSL</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="IdePreferencesSwitch">
+            <property name="visible">True</property>
+            <property name="key">strings-visible</property>
+            <property name="is-radio">True</property>
+            <property name="schema-id">org.gnome.builder.plugins.color_picker_plugin</property>
+            <property name="target">"hsla"</property>
+            <property name="title">HSLA</property>
+            <style>
+              <class name="cp-prefs-switch"/>
+            </style>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkBox" id="palettes_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin">6</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Palettes options</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+        <style>
+          <class name="cp-prefs-title"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">start</property>
+        <property name="label" translatable="yes">Palette view mode :</property>
+        <style>
+          <class name="cp-prefs-grouptitle"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox">
+        <property name="homogeneous">True</property>
+        <property name="visible">1</property>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">1</property>
+            <property name="halign">center</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">List</property>
+                <style>
+                  <class name="cp-prefs-grouptitle"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="viewmode_list_button">
+                <property name="name">viewmode_list_button</property>
+                <property name="action-name">gstyle-palettes-prefs.view-mode</property>
+                <property name="action-target">"list"</property>
+                <property name="visible">1</property>
+                <property name="can_focus">1</property>
+                <property name="receives_default">1</property>
+                <style>
+                  <class name="flat"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-name">builder-colorpicker-viewmode-list</property>
+                    <property name="pixel-size">48</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">1</property>
+            <property name="halign">center</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Swatchs</property>
+                <style>
+                  <class name="cp-prefs-grouptitle"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="viewmode_swatchs_button">
+                <property name="name">viewmode_swatchs_button</property>
+                <property name="action-name">gstyle-palettes-prefs.view-mode</property>
+                <property name="action-target">"swatchs"</property>
+                <property name="visible">1</property>
+                <property name="can_focus">1</property>
+                <property name="receives_default">1</property>
+                <style>
+                  <class name="flat"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-name">builder-colorpicker-viewmode-swatchs</property>
+                    <property name="pixel-size">48</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkBox" id="paletteslist_page">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin">6</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" translatable="yes">Palette selection</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+        <style>
+          <class name="cp-prefs-title"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkBox">
+        <property name="homogeneous">True</property>
+        <property name="visible">1</property>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">1</property>
+            <property name="halign">center</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Load</property>
+                <style>
+                  <class name="cp-prefs-grouptitle"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="load_palette_button">
+                <property name="name">load_palette_button</property>
+                <property name="visible">1</property>
+                <property name="can_focus">1</property>
+                <property name="receives_default">1</property>
+                <style>
+                  <class name="flat"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-name">builder-colorpicker-load-palette</property>
+                    <property name="pixel-size">48</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">1</property>
+            <property name="halign">center</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Save</property>
+                <style>
+                  <class name="cp-prefs-grouptitle"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="save_palette_button">
+                <property name="name">save_palette_button</property>
+                <property name="visible">1</property>
+                <property name="can_focus">1</property>
+                <property name="receives_default">1</property>
+                <style>
+                  <class name="flat"/>
+                </style>
+                <child>
+                  <object class="GtkImage">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon-name">builder-colorpicker-save-palette</property>
+                    <property name="pixel-size">48</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_top">6</property>
+        <property name="margin_bottom">6</property>
+        <property name="label" translatable="yes">Select the palette you want to see in the panel or close 
one.</property>
+        <property name="justify">fill</property>
+        <property name="wrap">True</property>
+        <style>
+          <class name="cp-prefs-resume"/>
+          <class name="dim-label"/>
+        </style>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GbColorPickerPrefsPaletteList" id="palettes_box">
+        <property name="visible">True</property>
+      </object>
+    </child>
+  </object>
+  <object class="GtkBox" id="palettes_placeholder">
+    <property name="expand">true</property>
+    <property name="halign">center</property>
+    <property name="margin">6</property>
+    <property name="spacing">12</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkImage">
+        <property name="icon-name">applications-graphics-symbolic</property>
+        <property name="pixel-size">32</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="label" translatable="yes">No loaded palettes</property>
+        <property name="halign">center</property>
+        <property name="hexpand">True</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+        <attributes>
+          <attribute name="scale" value="1.0"/>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/plugins/color-picker/gtk/color-picker-preview.ui 
b/plugins/color-picker/gtk/color-picker-preview.ui
new file mode 100644
index 0000000..2e498d0
--- /dev/null
+++ b/plugins/color-picker/gtk/color-picker-preview.ui
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.16"/>
+  <object class="GtkBox" id="preview">
+    <property name="name">colorpicker_palette_preview</property>
+    <property name="expand">true</property>
+    <property name="halign">fill</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkLabel" id="preview_title">
+        <property name="name">colorpicker_preview_title</property>
+        <property name="visible">true</property>
+        <property name="ellipsize">middle</property>
+        <property name="hexpand">true</property>
+        <property name="halign">center</property>
+      </object>
+    </child>
+    <child>
+      <object class="GstylePaletteWidget" id="preview_palette_widget">
+        <property name="visible">1</property>
+        <property name="expand">true</property>
+      </object>
+    </child>
+  </object>
+  <object class="GtkBox" id="preview_placeholder">
+    <property name="expand">true</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkImage">
+        <property name="icon-name">applications-graphics-symbolic</property>
+        <property name="pixel-size">128</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="label" translatable="yes">No selected palettes</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+        <attributes>
+          <attribute name="scale" value="2.0"/>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="label" translatable="yes">Select a palette file</property>
+        <property name="wrap">true</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+  </object>
+</interface>
+
diff --git a/plugins/color-picker/gtk/color-picker.ui b/plugins/color-picker/gtk/color-picker.ui
new file mode 100644
index 0000000..37cb141
--- /dev/null
+++ b/plugins/color-picker/gtk/color-picker.ui
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.19.0 -->
+<interface>
+  <requires lib="gtk+" version="3.16"/>
+  <object class="GtkBox" id="color_picker">
+    <property name="visible">1</property>
+    <property name="expand">true</property>
+    <property name="margin">6</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <child>
+      <object class="GtkColorChooserWidget" id="colorchooserwidget">
+        <property name="visible">true</property>
+        <property name="valign">start</property>
+        <property name="show_editor">1</property>
+      </object>
+      <packing>
+        <property name="expand">true</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GstylePaletteWidget" id="palette_widget">
+        <property name="visible">1</property>
+        <property name="expand">true</property>
+      </object>
+      <packing>
+        <property name="expand">true</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkBox" id="palette_widget_placeholder">
+    <property name="expand">true</property>
+    <property name="orientation">vertical</property>
+    <property name="spacing">12</property>
+    <property name="visible">true</property>
+    <child>
+      <object class="GtkImage">
+        <property name="icon-name">applications-graphics-symbolic</property>
+        <property name="pixel-size">128</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="label" translatable="yes">No open palettes</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+        <attributes>
+          <attribute name="scale" value="2.0"/>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="label" translatable="yes">Try loading or generating a palette by using the 
menu</property>
+        <property name="wrap">true</property>
+        <property name="visible">true</property>
+        <style>
+          <class name="dim-label"/>
+        </style>
+      </object>
+    </child>
+  </object>
+</interface>
+
diff --git a/plugins/color-picker/gtk/menus.ui b/plugins/color-picker/gtk/menus.ui
new file mode 100644
index 0000000..2819213
--- /dev/null
+++ b/plugins/color-picker/gtk/menus.ui
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<interface>
+  <menu id="ide-source-view-popup-menu">
+    <section id="ide-source-view-popup-menu-colorpicker-section">
+      <attribute name="after">ide-source-view-popup-menu-zoom-section</attribute>
+      <item>
+        <attribute name="label" translatable="yes">Color picker activated</attribute>
+        <attribute name="action">view.activate-color-picker</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/plugins/color-picker/icons/assets.svg b/plugins/color-picker/icons/assets.svg
new file mode 100644
index 0000000..16be300
--- /dev/null
+++ b/plugins/color-picker/icons/assets.svg
@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   width="98"
+   height="98"
+   id="svg7384"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="assets.svg">
+  <metadata
+     id="metadata90">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#8ce0f0"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="1"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1016"
+     id="namedview88"
+     showgrid="false"
+     inkscape:zoom="1.5753505"
+     inkscape:cx="19.603718"
+     inkscape:cy="64.78169"
+     inkscape:window-x="1920"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer3"
+     showborder="false"
+     inkscape:snap-nodes="true"
+     inkscape:snap-bbox="true"
+     inkscape:bbox-paths="true"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:snap-to-guides="true"
+     inkscape:snap-grids="true"
+     inkscape:snap-global="true"
+     inkscape:object-nodes="true"
+     inkscape:snap-bbox-midpoints="false"
+     inkscape:object-paths="true"
+     inkscape:snap-others="true"
+     inkscape:bbox-nodes="true"
+     borderlayer="true"
+     inkscape:showpageshadow="false"
+     inkscape:snap-intersection-paths="true"
+     inkscape:snap-smooth-nodes="true"
+     inkscape:snap-midpoints="true">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4866"
+       empspacing="2"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="1px"
+       spacingy="1px" />
+  </sodipodi:namedview>
+  <title
+     id="title9167">Gnome Symbolic Icon Theme</title>
+  <defs
+     id="defs7386" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="palette"
+     transform="translate(0,82)">
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot4199"
+       
style="font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       transform="translate(0,-82)"><flowRegion
+         id="flowRegion4201"><rect
+           id="rect4203"
+           width="224"
+           height="63"
+           x="-17"
+           y="-90" /></flowRegion><flowPara
+         id="flowPara4205" /></flowRoot>    <g
+       id="g4257"
+       transform="translate(132.40397,-83.5)"
+       inkscape:label="save-palette">
+      <rect
+         
style="color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new"
+         id="rect23109"
+         width="95"
+         height="95"
+         x="-11.195584"
+         y="-80.5"
+         rx="3.8039246"
+         ry="3.8039246"
+         transform="translate(0,82)" />
+      <path
+         sodipodi:nodetypes="ccccccssccsssssssssssssssssssssssss"
+         inkscape:connector-curvature="0"
+         id="path9234"
+         d="m 33.61469,7.734762 c -0.306649,-0.01151 -0.681531,-0.0046 -1.005352,0 -4.857206,0.06814 
-11.384465,1.846814 -11.274514,7.55264 0.114877,5.953562 5.677773,4.268134 7.476952,5.898186 
1.972254,1.718512 2.222946,2.650023 0.09625,6.237658 -1.736702,2.222143 -2.993749,4.641038 -2.689978,7.141427 
0.331225,3.288751 1.866912,6.322527 7.468473,7.4088 C 42.660507,43.713742 52.165538,37.77381 
51.208646,25.717276 50.797895,20.542121 47.834532,14.701601 43.083667,11.409419 39.843234,9.302573 
36.006676,7.813427 33.61469,7.734762 Z m -5.385895,3.524556 c 1.903699,0 3.446971,1.545807 3.446971,3.452661 
0,1.906852 -1.543272,3.452635 -3.446971,3.452635 -1.903723,0 -3.446974,-1.545783 -3.446974,-3.452635 
0,-1.906854 1.543251,-3.452661 3.446974,-3.452661 z m 17.522127,10.286013 c 1.263424,0 2.29799,1.030538 
2.29799,2.301765 0,1.271205 -1.034566,2.301767 -2.29799,2.301767 -1.263402,0 -2.297967,-1.030562 
-2.297967,-2.301767 0,-1.271227 1.034565,-2.301765 2.297967,-2.301765 z m -1.43622
 3,6.905297 c 1.2634,0 2.297967,1.030536 2.297967,2.301765 0,1.271205 -1.034567,2.301741 -2.297967,2.301741 
-1.263423,0 -2.29799,-1.030536 -2.29799,-2.301741 0,-1.271229 1.034567,-2.301765 2.29799,-2.301765 z m 
-11.489926,4.603506 c 1.2634,0 2.297967,1.030562 2.297967,2.301767 0,1.271227 -1.034567,2.301765 
-2.297967,2.301765 -1.263423,0 -2.29799,-1.030538 -2.29799,-2.301765 0,-1.271205 1.034567,-2.301767 
2.29799,-2.301767 z m 6.893946,0 c 1.263423,0 2.29799,1.030562 2.29799,2.301767 0,1.271227 -1.034567,2.301765 
-2.29799,2.301765 -1.263424,0 -2.297989,-1.030538 -2.297989,-2.301765 0,-1.271205 1.034565,-2.301767 
2.297989,-2.301767 z"
+         style="fill:#729fcf" />
+      <path
+         sodipodi:nodetypes="cccc"
+         inkscape:connector-curvature="0"
+         id="path4227"
+         d="m 7.5775809,71.340869 0,13.642284 57.4536701,0 0,-13.642284"
+         
style="opacity:0.98999999;fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linejoin:round" />
+      <path
+         sodipodi:nodetypes="ccccc"
+         inkscape:connector-curvature="0"
+         d="m 36.107883,69.902603 0,-16.259351 m -8.175077,9.508139 8.175077,6.751212 8.567917,-6.931245"
+         
style="fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linecap:round;stroke-linejoin:round"
+         id="path4244" />
+    </g>
+    <g
+       id="g4265"
+       transform="translate(-109.71514,-83.5)"
+       inkscape:label="load-palette">
+      <rect
+         ry="3.8039246"
+         rx="3.8039246"
+         y="-80.5"
+         x="103.40434"
+         height="95"
+         width="95"
+         id="rect7496"
+         
style="color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new"
+         transform="translate(0,82)" />
+      <rect
+         y="-82"
+         x="101.90434"
+         height="98"
+         width="98"
+         id="rect7544"
+         
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:none;stroke-width:0.99999976;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         transform="translate(0,82)" />
+      <path
+         style="fill:#729fcf"
+         d="m 148.21464,9.085208 c -0.30665,-0.01151 -0.68153,-0.0046 -1.00535,0 -4.85721,0.06814 
-11.38447,1.846814 -11.27452,7.55264 0.11488,5.953562 5.67778,4.268134 7.47696,5.898186 1.97225,1.718512 
2.22294,2.650023 0.0962,6.237658 -1.73671,2.222143 -2.99375,4.641038 -2.68998,7.141427 0.33122,3.288751 
1.86691,6.322527 7.46847,7.4088 8.97399,1.740269 18.47902,-4.199663 17.52213,-16.256197 -0.41076,-5.175155 
-3.37412,-11.015675 -8.12498,-14.307857 -3.24044,-2.106846 -7.07699,-3.595992 -9.46898,-3.674657 z m 
-5.3859,3.524556 c 1.9037,0 3.44698,1.545807 3.44698,3.452661 0,1.906852 -1.54328,3.452635 -3.44698,3.452635 
-1.90372,0 -3.44697,-1.545783 -3.44697,-3.452635 0,-1.906854 1.54325,-3.452661 3.44697,-3.452661 z m 
17.52213,10.286013 c 1.26343,0 2.29799,1.030538 2.29799,2.301765 0,1.271205 -1.03456,2.301767 
-2.29799,2.301767 -1.2634,0 -2.29797,-1.030562 -2.29797,-2.301767 0,-1.271227 1.03457,-2.301765 
2.29797,-2.301765 z m -1.43622,6.905297 c 1.2634,0 2.29797,1.030536 2.2979
 7,2.301765 0,1.271205 -1.03457,2.301741 -2.29797,2.301741 -1.26342,0 -2.29799,-1.030536 -2.29799,-2.301741 
0,-1.271229 1.03457,-2.301765 2.29799,-2.301765 z m -11.48993,4.603506 c 1.2634,0 2.29797,1.030562 
2.29797,2.301767 0,1.271227 -1.03457,2.301765 -2.29797,2.301765 -1.26342,0 -2.29799,-1.030538 
-2.29799,-2.301765 0,-1.271205 1.03457,-2.301767 2.29799,-2.301767 z m 6.89395,0 c 1.26342,0 2.29799,1.030562 
2.29799,2.301767 0,1.271227 -1.03457,2.301765 -2.29799,2.301765 -1.26343,0 -2.29799,-1.030538 
-2.29799,-2.301765 0,-1.271205 1.03456,-2.301767 2.29799,-2.301767 z"
+         id="path4250"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccccssccsssssssssssssssssssssssss" />
+      <path
+         
style="opacity:0.98999999;fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linejoin:round"
+         d="m 122.17751,72.691315 0,13.642284 57.45367,0 0,-13.642284"
+         id="path4252"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccc" />
+      <path
+         id="path4254"
+         
style="fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linecap:round;stroke-linejoin:round"
+         d="m 150.7078,54.993698 0,16.259351 m -8.17507,-9.508139 8.17507,-6.751212 8.56792,6.931245"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="ccccc" />
+    </g>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="viewmode">
+    <g
+       inkscape:label="viewmode-swatchs"
+       id="g4258"
+       transform="translate(-156.63793,-520.42474)"
+       style="opacity:0.98999999">
+      <g
+         id="g4308"
+         transform="translate(36.357401,-45.783394)"
+         inkscape:label="viewmode-swatchs">
+        <rect
+           
style="color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new"
+           id="rect4260"
+           width="95"
+           height="95"
+           x="413.56213"
+           y="567.25928"
+           rx="3.8039246"
+           ry="3.8039246" />
+        <g
+           transform="translate(-19.127573,40.370519)"
+           id="g4287">
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="557.10455"
+             x="442.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4284"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.59358287;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.87165773;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4286"
+             width="15.026019"
+             height="15.026019"
+             x="462.6767"
+             y="557.10455"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="557.10455"
+             x="482.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4288"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.62566845;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4290"
+             width="15.026019"
+             height="15.026019"
+             x="502.6767"
+             y="557.10455"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.76470588;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4292"
+             width="15.026019"
+             height="15.026019"
+             x="442.6767"
+             y="577.10455"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="577.10455"
+             x="462.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4294"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.61497324;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4296"
+             width="15.026019"
+             height="15.026019"
+             x="482.6767"
+             y="577.10455"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="577.10455"
+             x="502.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4298"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.53475934;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="597.10455"
+             x="442.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4300"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.36363639;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4302"
+             width="15.026019"
+             height="15.026019"
+             x="462.6767"
+             y="597.10455"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="597.10455"
+             x="482.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4304"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.58823529;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4306"
+             width="15.026019"
+             height="15.026019"
+             x="502.6767"
+             y="597.10455"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4275"
+             width="15.026019"
+             height="15.026019"
+             x="442.6767"
+             y="536.64697"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="536.64697"
+             x="462.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4277"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.64171125;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.87700536;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+             id="rect4279"
+             width="15.026019"
+             height="15.026019"
+             x="482.6767"
+             y="536.64697"
+             rx="1.2406625"
+             ry="1.2406625" />
+          <rect
+             ry="1.2406625"
+             rx="1.2406625"
+             y="536.64697"
+             x="502.6767"
+             height="15.026019"
+             width="15.026019"
+             id="rect4281"
+             
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.58288772;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+          <rect
+             transform="translate(139.85697,525.38877)"
+             y="0"
+             x="0"
+             height="0"
+             width="0"
+             id="rect4305"
+             style="fill:#bdd2e9;fill-opacity:0.87165773;stroke-width:5;stroke-linecap:round" />
+        </g>
+      </g>
+    </g>
+    <g
+       transform="translate(-47.116875,-520.42474)"
+       id="g4329"
+       inkscape:label="viewmode-list">
+      <g
+         id="g4411">
+        <rect
+           ry="3.8039246"
+           rx="3.8039246"
+           y="521.47589"
+           x="449.91953"
+           height="95"
+           width="95"
+           id="rect4333"
+           
style="color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new"
 />
+        <rect
+           ry="0"
+           rx="0"
+           y="551.69165"
+           x="459.90652"
+           height="15.026019"
+           width="73.826248"
+           id="rect4337"
+           
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.59358287;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+        <rect
+           
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.76470588;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+           id="rect4345"
+           width="73.826248"
+           height="15.026019"
+           x="459.90652"
+           y="571.69165"
+           rx="0"
+           ry="0" />
+        <rect
+           ry="0"
+           rx="0"
+           y="591.69165"
+           x="459.90652"
+           height="15.026019"
+           width="73.826248"
+           id="rect4353"
+           
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.36363639;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
 />
+        <rect
+           
style="color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new"
+           id="rect4361"
+           width="72.928543"
+           height="15.026019"
+           x="460.95526"
+           y="530.78522"
+           rx="0"
+           ry="0" />
+      </g>
+      <rect
+         style="fill:#bdd2e9;fill-opacity:0.87165773;stroke-width:5;stroke-linecap:round"
+         id="rect4369"
+         width="0"
+         height="0"
+         x="157.08681"
+         y="519.97589" />
+    </g>
+    <rect
+       style="fill:none"
+       id="rect9299"
+       width="44.484322"
+       height="44.557446"
+       x="-96.234314"
+       y="-9.7832813"
+       rx="5.3693833"
+       ry="0" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer1"
+     inkscape:label="text"
+     sodipodi:insensitive="true"
+     style="display:none">
+    <text
+       xml:space="preserve"
+       style="font-size:25px;line-height:125%;font-family:'Andale Mono';-inkscape-font-specification:'Andale 
Mono, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:1px"
+       x="-122"
+       y="-94"
+       id="text4208"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan4212"
+         x="-122"
+         y="-94" /></text>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot4214"
+       style="font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px"><flowRegion
+         id="flowRegion4216"><rect
+           id="rect4218"
+           width="392"
+           height="52"
+           x="-350"
+           y="-163"
+           
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell,
 Normal';text-align:start;writing-mode:lr-tb;text-anchor:start" /></flowRegion><flowPara
+         id="flowPara4220" /></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot4222"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px"><flowRegion
+         id="flowRegion4224"><rect
+           id="rect4226"
+           width="401"
+           height="51"
+           x="-125"
+           y="-207" /></flowRegion><flowPara
+         id="flowPara4228" /></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot4230"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       transform="translate(184,-314.56579)"><flowRegion
+         id="flowRegion4232"><rect
+           id="rect4234"
+           width="153"
+           height="39"
+           x="-163"
+           y="207" /></flowRegion><flowPara
+         id="flowPara4236"
+         style="font-size:25px;line-height:125%;-inkscape-font-specification:'Cantarell, 
Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle">palettes</flowPara></flowRoot>    <flowRoot
+       transform="translate(232,-254.24079)"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       id="flowRoot4238"
+       xml:space="preserve"><flowRegion
+         id="flowRegion4240"><rect
+           y="207"
+           x="-163"
+           height="39"
+           width="153"
+           id="rect4242" /></flowRegion><flowPara
+         style="font-size:25px;line-height:125%;-inkscape-font-specification:'Cantarell, 
Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle"
+         id="flowPara4244">save</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot4246"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       transform="translate(137,-254.21579)"><flowRegion
+         id="flowRegion4248"><rect
+           id="rect4250"
+           width="153"
+           height="39"
+           x="-163"
+           y="207" /></flowRegion><flowPara
+         id="flowPara4252"
+         style="font-size:25px;line-height:125%;-inkscape-font-specification:'Cantarell, 
Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle">load</flowPara></flowRoot>    <flowRoot
+       transform="translate(487,-314.56579)"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       id="flowRoot4358"
+       xml:space="preserve"><flowRegion
+         id="flowRegion4360"><rect
+           y="207"
+           x="-163"
+           height="39"
+           width="153"
+           id="rect4362" /></flowRegion><flowPara
+         style="font-size:25px;line-height:125%;-inkscape-font-specification:'Cantarell, 
Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle"
+         id="flowPara4364">view mode</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot4366"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       transform="translate(535,-254.24079)"><flowRegion
+         id="flowRegion4368"><rect
+           id="rect4370"
+           width="153"
+           height="39"
+           x="-163"
+           y="207" /></flowRegion><flowPara
+         id="flowPara4372"
+         style="font-size:25px;line-height:125%;-inkscape-font-specification:'Cantarell, 
Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle">swatchs</flowPara></flowRoot>    <flowRoot
+       transform="translate(440,-254.21579)"
+       style="font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:'Cantarell, 
Normal';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px"
+       id="flowRoot4374"
+       xml:space="preserve"><flowRegion
+         id="flowRegion4376"><rect
+           y="207"
+           x="-163"
+           height="39"
+           width="153"
+           id="rect4378" /></flowRegion><flowPara
+         style="font-size:25px;line-height:125%;-inkscape-font-specification:'Cantarell, 
Normal';text-align:center;writing-mode:lr-tb;text-anchor:middle"
+         id="flowPara4380">list</flowPara></flowRoot>  </g>
+</svg>
diff --git a/plugins/color-picker/icons/assets.txt b/plugins/color-picker/icons/assets.txt
new file mode 100644
index 0000000..69acf39
--- /dev/null
+++ b/plugins/color-picker/icons/assets.txt
@@ -0,0 +1,2 @@
+save-palette
+load-palette
diff --git a/plugins/color-picker/icons/palette/load-palette.svg 
b/plugins/color-picker/icons/palette/load-palette.svg
new file mode 100644
index 0000000..df62903
--- /dev/null
+++ b/plugins/color-picker/icons/palette/load-palette.svg
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' 
sodipodi:docname='load-palette.svg' height='98' id='svg7384' 
xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' 
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' 
xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' 
version='1.1' inkscape:version='0.91 r13725' width='98' xmlns='http://www.w3.org/2000/svg'>
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='true' inkscape:bbox-paths='true' bordercolor='#666666' 
borderlayer='true' borderopacity='1' inkscape:current-layer='layer3' inkscape:cx='28.684074' 
inkscape:cy='62.012131' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' 
inkscape:object-nodes='true' inkscape:object-paths='true' objecttolerance='10' pagecolor='#8ce0f0' 
inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' 
inkscape:showpageshadow='false' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' 
inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-intersection-paths='true' 
inkscape:snap-midpoints='true' inkscape:snap-nodes='true' inkscape:snap-others='true' 
inkscape:snap-smooth-nodes='true' inkscape:snap-to-guides='true' inkscape:window-height='1016' 
inkscape:window-maximized='1' inkscape:window-width='1920' inkscape:window-x='1920' inkscape:window-y='27' 
inkscape:zo
 om='1.5753505'>
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='7.8107973' originy='-1.5' 
snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'/>
+  <g inkscape:groupmode='layer' id='layer3' inkscape:label='palette' transform='translate(7.8107973,83.5)'>
+    <rect height='95' id='rect7496' rx='3.8039246' ry='3.8039246' 
style='color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new'
 width='95' x='-6.3107972' y='-82'/>
+    <rect height='98' id='rect7544' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:none;stroke-width:0.99999976;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:accumulate'
 width='98' x='-7.8107972' y='-83.5'/>
+    <path inkscape:connector-curvature='0' d='m 38.4995,-74.414792 c -0.30665,-0.01151 -0.68153,-0.0046 
-1.00535,0 -4.85721,0.06814 -11.38447,1.846814 -11.27452,7.55264 0.11488,5.953562 5.67778,4.268134 
7.47696,5.898186 1.97225,1.718512 2.22294,2.650023 0.0962,6.237658 -1.73671,2.222143 -2.99375,4.641038 
-2.68998,7.141427 0.33122,3.288751 1.86691,6.322527 7.46847,7.4088 8.97399,1.740269 18.47902,-4.199663 
17.52213,-16.256197 -0.41076,-5.175155 -3.37412,-11.015675 -8.12498,-14.307857 -3.24044,-2.106846 
-7.07699,-3.595992 -9.46898,-3.674657 z m -5.3859,3.524556 c 1.9037,0 3.44698,1.545807 3.44698,3.452661 
0,1.906852 -1.54328,3.452635 -3.44698,3.452635 -1.90372,0 -3.44697,-1.545783 -3.44697,-3.452635 0,-1.906854 
1.54325,-3.452661 3.44697,-3.452661 z m 17.52213,10.286013 c 1.26343,0 2.29799,1.030538 2.29799,2.301765 
0,1.271205 -1.03456,2.301767 -2.29799,2.301767 -1.2634,0 -2.29797,-1.030562 -2.29797,-2.301767 0,-1.271227 
1.03457,-2.301765 2.29797,-2.301765 z m -1.43622,6.905297 
 c 1.2634,0 2.29797,1.030536 2.29797,2.301765 0,1.271205 -1.03457,2.301741 -2.29797,2.301741 -1.26342,0 
-2.29799,-1.030536 -2.29799,-2.301741 0,-1.271229 1.03457,-2.301765 2.29799,-2.301765 z m -11.48993,4.603506 
c 1.2634,0 2.29797,1.030562 2.29797,2.301767 0,1.271227 -1.03457,2.301765 -2.29797,2.301765 -1.26342,0 
-2.29799,-1.030538 -2.29799,-2.301765 0,-1.271205 1.03457,-2.301767 2.29799,-2.301767 z m 6.89395,0 c 
1.26342,0 2.29799,1.030562 2.29799,2.301767 0,1.271227 -1.03457,2.301765 -2.29799,2.301765 -1.26343,0 
-2.29799,-1.030538 -2.29799,-2.301765 0,-1.271205 1.03456,-2.301767 2.29799,-2.301767 z' id='path4250' 
sodipodi:nodetypes='ccccccssccsssssssssssssssssssssssss' style='fill:#729fcf'/>
+    <path inkscape:connector-curvature='0' d='m 12.46237,-10.808685 0,13.642284 57.45367,0 0,-13.642284' 
id='path4252' sodipodi:nodetypes='cccc' 
style='opacity:0.98999999;fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linejoin:round'/>
+    <path inkscape:connector-curvature='0' d='m 40.99266,-28.506302 0,16.259351 m -8.17507,-9.508139 
8.17507,-6.751212 8.56792,6.931245' id='path4254' sodipodi:nodetypes='ccccc' 
style='fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linecap:round;stroke-linejoin:round'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer2' inkscape:label='viewmode' transform='translate(7.8107973,1.5)'/>
+  <g inkscape:groupmode='layer' id='layer1' sodipodi:insensitive='true' inkscape:label='text' 
style='display:none' transform='translate(7.8107973,1.5)'>
+    <text id='text4208' sodipodi:linespacing='125%' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:&apos;Andale 
Mono&apos;;-inkscape-font-specification:&apos;Andale Mono, 
Normal&apos;;text-align:start;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:1px' x='-122' 
y='-94'><tspan id='tspan4212' sodipodi:role='line' x='-122' y='-94'/></text>
+    <flowRoot id='flowRoot4214' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4216'><rect height='52' id='rect4218' 
style='font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell,
 Normal&apos;;text-align:start;writing-mode:lr-tb;text-anchor:start' width='392' x='-350' 
y='-163'/></flowRegion><flowPara id='flowPara4220'/></flowRoot>    <flowRoot id='flowRoot4222' 
xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4224'><rect height='51' id='rect4226' width='401' x='-125' y='-207'/></
 flowRegion><flowPara id='flowPara4228'/></flowRoot>    <flowRoot id='flowRoot4230' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(184,-314.56579)'><flowRegion id='flowRegion4232'><rect height='39' id='rect4234' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4236' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>palettes</flowPara></flowRoot>    
<flowRoot id='flowRoot4238' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(232,-254.24079)'><flowRegion id='flowRegi
 on4240'><rect height='39' id='rect4242' width='153' x='-163' y='207'/></flowRegion><flowPara 
id='flowPara4244' style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>save</flowPara></flowRoot>    <flowRoot 
id='flowRoot4246' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(137,-254.21579)'><flowRegion id='flowRegion4248'><rect height='39' id='rect4250' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4252' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>load</flowPara></flowRoot>    <flowRoot 
id='flowRoot4358' xml:space='preserve' style='font-size:40px;line-heig
 ht:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(487,-314.56579)'><flowRegion id='flowRegion4360'><rect height='39' id='rect4362' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4364' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>view mode</flowPara></flowRoot>    
<flowRoot id='flowRoot4366' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(535,-254.24079)'><flowRegion id='flowRegion4368'><rect height='39' id='rect4370' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4372' style='font-size:25px;l
 ine-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>swatchs</flowPara></flowRoot>    
<flowRoot id='flowRoot4374' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(440,-254.21579)'><flowRegion id='flowRegion4376'><rect height='39' id='rect4378' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4380' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>list</flowPara></flowRoot>  </g>
+</svg>
diff --git a/plugins/color-picker/icons/palette/save-palette.svg 
b/plugins/color-picker/icons/palette/save-palette.svg
new file mode 100644
index 0000000..214e393
--- /dev/null
+++ b/plugins/color-picker/icons/palette/save-palette.svg
@@ -0,0 +1,29 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' 
sodipodi:docname='save-palette.svg' height='98' id='svg7384' 
xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' 
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' 
xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' 
version='1.1' inkscape:version='0.91 r13725' width='98' xmlns='http://www.w3.org/2000/svg'>
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='true' inkscape:bbox-paths='true' bordercolor='#666666' 
borderlayer='true' borderopacity='1' inkscape:current-layer='layer3' inkscape:cx='-98.835109' 
inkscape:cy='62.012131' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' 
inkscape:object-nodes='true' inkscape:object-paths='true' objecttolerance='10' pagecolor='#8ce0f0' 
inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' 
inkscape:showpageshadow='false' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' 
inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-intersection-paths='true' 
inkscape:snap-midpoints='true' inkscape:snap-nodes='true' inkscape:snap-others='true' 
inkscape:snap-smooth-nodes='true' inkscape:snap-to-guides='true' inkscape:window-height='1016' 
inkscape:window-maximized='1' inkscape:window-width='1920' inkscape:window-x='1920' inkscape:window-y='27' 
inkscape:z
 oom='1.5753505'>
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-119.70839' originy='-1.5' 
snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'/>
+  <g inkscape:groupmode='layer' id='layer3' inkscape:label='palette' transform='translate(-119.70839,83.5)'>
+    <rect height='95' id='rect23109' rx='3.8039246' ry='3.8039246' 
style='color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new'
 width='95' x='121.20839' y='-82'/>
+    <path inkscape:connector-curvature='0' d='m 166.01866,-75.765238 c -0.30665,-0.01151 -0.68153,-0.0046 
-1.00535,0 -4.85721,0.06814 -11.38447,1.846814 -11.27452,7.55264 0.11488,5.953562 5.67778,4.268134 
7.47696,5.898186 1.97225,1.718512 2.22294,2.650023 0.0962,6.237658 -1.73671,2.222143 -2.99375,4.641038 
-2.68998,7.141427 0.33122,3.288751 1.86691,6.322527 7.46847,7.4088 8.97399,1.740269 18.47902,-4.199663 
17.52213,-16.256197 -0.41076,-5.175155 -3.37412,-11.015675 -8.12498,-14.307857 -3.24044,-2.106846 
-7.07699,-3.595992 -9.46898,-3.674657 z m -5.3859,3.524556 c 1.9037,0 3.44698,1.545807 3.44698,3.452661 
0,1.906852 -1.54328,3.452635 -3.44698,3.452635 -1.90372,0 -3.44697,-1.545783 -3.44697,-3.452635 0,-1.906854 
1.54325,-3.452661 3.44697,-3.452661 z m 17.52213,10.286013 c 1.26343,0 2.29799,1.030538 2.29799,2.301765 
0,1.271205 -1.03456,2.301767 -2.29799,2.301767 -1.2634,0 -2.29797,-1.030562 -2.29797,-2.301767 0,-1.271227 
1.03457,-2.301765 2.29797,-2.301765 z m -1.43622,6.90529
 7 c 1.2634,0 2.29797,1.030536 2.29797,2.301765 0,1.271205 -1.03457,2.301741 -2.29797,2.301741 -1.26342,0 
-2.29799,-1.030536 -2.29799,-2.301741 0,-1.271229 1.03457,-2.301765 2.29799,-2.301765 z m -11.48993,4.603506 
c 1.2634,0 2.29797,1.030562 2.29797,2.301767 0,1.271227 -1.03457,2.301765 -2.29797,2.301765 -1.26342,0 
-2.29799,-1.030538 -2.29799,-2.301765 0,-1.271205 1.03457,-2.301767 2.29799,-2.301767 z m 6.89395,0 c 
1.26342,0 2.29799,1.030562 2.29799,2.301767 0,1.271227 -1.03457,2.301765 -2.29799,2.301765 -1.26343,0 
-2.29799,-1.030538 -2.29799,-2.301765 0,-1.271205 1.03456,-2.301767 2.29799,-2.301767 z' id='path9234' 
sodipodi:nodetypes='ccccccssccsssssssssssssssssssssssss' style='fill:#729fcf'/>
+    <path inkscape:connector-curvature='0' d='m 139.98155,-12.159131 0,13.642284 57.45367,0 0,-13.642284' 
id='path4227' sodipodi:nodetypes='cccc' 
style='opacity:0.98999999;fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linejoin:round'/>
+    <path inkscape:connector-curvature='0' d='m 168.51185,-13.597397 0,-16.259351 m -8.17507,9.508139 
8.17507,6.751212 8.56792,-6.931245' id='path4244' sodipodi:nodetypes='ccccc' 
style='fill:none;fill-rule:evenodd;stroke:#729fcf;stroke-width:5;stroke-linecap:round;stroke-linejoin:round'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer2' inkscape:label='viewmode' transform='translate(-119.70839,1.5)'/>
+  <g inkscape:groupmode='layer' id='layer1' sodipodi:insensitive='true' inkscape:label='text' 
style='display:none' transform='translate(-119.70839,1.5)'>
+    <text id='text4208' sodipodi:linespacing='125%' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:&apos;Andale 
Mono&apos;;-inkscape-font-specification:&apos;Andale Mono, 
Normal&apos;;text-align:start;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:1px' x='-122' 
y='-94'><tspan id='tspan4212' sodipodi:role='line' x='-122' y='-94'/></text>
+    <flowRoot id='flowRoot4214' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4216'><rect height='52' id='rect4218' 
style='font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell,
 Normal&apos;;text-align:start;writing-mode:lr-tb;text-anchor:start' width='392' x='-350' 
y='-163'/></flowRegion><flowPara id='flowPara4220'/></flowRoot>    <flowRoot id='flowRoot4222' 
xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4224'><rect height='51' id='rect4226' width='401' x='-125' y='-207'/></
 flowRegion><flowPara id='flowPara4228'/></flowRoot>    <flowRoot id='flowRoot4230' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(184,-314.56579)'><flowRegion id='flowRegion4232'><rect height='39' id='rect4234' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4236' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>palettes</flowPara></flowRoot>    
<flowRoot id='flowRoot4238' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(232,-254.24079)'><flowRegion id='flowRegi
 on4240'><rect height='39' id='rect4242' width='153' x='-163' y='207'/></flowRegion><flowPara 
id='flowPara4244' style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>save</flowPara></flowRoot>    <flowRoot 
id='flowRoot4246' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(137,-254.21579)'><flowRegion id='flowRegion4248'><rect height='39' id='rect4250' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4252' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>load</flowPara></flowRoot>    <flowRoot 
id='flowRoot4358' xml:space='preserve' style='font-size:40px;line-heig
 ht:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(487,-314.56579)'><flowRegion id='flowRegion4360'><rect height='39' id='rect4362' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4364' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>view mode</flowPara></flowRoot>    
<flowRoot id='flowRoot4366' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(535,-254.24079)'><flowRegion id='flowRegion4368'><rect height='39' id='rect4370' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4372' style='font-size:25px;l
 ine-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>swatchs</flowPara></flowRoot>    
<flowRoot id='flowRoot4374' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(440,-254.21579)'><flowRegion id='flowRegion4376'><rect height='39' id='rect4378' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4380' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>list</flowPara></flowRoot>  </g>
+</svg>
diff --git a/plugins/color-picker/icons/render-assets.py b/plugins/color-picker/icons/render-assets.py
new file mode 100755
index 0000000..0fb4d00
--- /dev/null
+++ b/plugins/color-picker/icons/render-assets.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python3
+
+import os
+import subprocess
+import shutil
+
+INKSCAPE = "/usr/bin/inkscape"
+SVG_SRC = "assets-symbolic.svg"
+TXT_SRC = "assets-symbolic.txt"
+
+CWD = os.getcwd()
+
+class Exporter(object):
+    def __init__(self):
+        self.ids = []
+        with open(TXT_SRC) as input_file:
+            for line in input_file:
+                self.ids.append(line.strip())
+
+    def start(self):
+        for id in self.ids:
+            self.export (id)
+            print("id:'{}' exported".format(id))
+
+    def export(self, id):
+        src = "".join([CWD, "/", SVG_SRC])
+        dst = "".join([CWD, "/", id, ".svg"])
+        shutil.copyfile (src, dst)
+        self.call_inkscape([dst,
+                            "--select={}".format(id),
+                            "--verb=FitCanvasToSelection",
+                            "--verb=EditInvertInAllLayers",
+                            "--verb=EditDelete",
+                            "--verb=EditSelectAll",
+                            "--verb=SelectionUnGroup",
+                            "--verb=SelectionUnGroup",
+                            "--verb=SelectionUnGroup",
+                            "--verb=StrokeToPath",
+                            "--verb=FileVacuum",
+                            "--verb=FileSave",
+                            "--verb=FileClose",
+                            "--verb=FileQuit"])
+
+    def call_inkscape(self, cmd):
+        cmd.insert(0, INKSCAPE)
+        subprocess.run(cmd, stdout=subprocess.PIPE)
+
+if __name__ == "__main__":
+    app = Exporter()
+    app.start()
diff --git a/plugins/color-picker/icons/render-assets.rb b/plugins/color-picker/icons/render-assets.rb
new file mode 100755
index 0000000..a2ac244
--- /dev/null
+++ b/plugins/color-picker/icons/render-assets.rb
@@ -0,0 +1,79 @@
+#!/usr/bin/env ruby
+
+require "rexml/document"
+require "fileutils"
+include REXML
+
+
+INKSCAPE = '/usr/bin/inkscape'
+#INKSCAPE = '/usr/bin/inkscape' # like this works for me, while using `which` inkscape hangs
+SRC = "assets.svg"
+PREFIX = "."
+
+def chopSVG(icon)
+       FileUtils.mkdir_p(icon[:dir]) unless File.exists?(icon[:dir])
+       unless (File.exists?(icon[:file]) && !icon[:forcerender])
+               FileUtils.cp(SRC,icon[:file])
+               puts " >> #{icon[:name]}"
+               cmd = "#{INKSCAPE} -f #{icon[:file]} --select #{icon[:id]} --verb=FitCanvasToSelection  
--verb=EditInvertInAllLayers "
+               cmd += "--verb=EditDelete --verb=EditSelectAll --verb=SelectionUnGroup 
--verb=SelectionUnGroup --verb=SelectionUnGroup --verb=FileVacuum "
+               cmd += "--verb=FileSave --verb=FileClose > /dev/null 2>&1"
+               system(cmd)
+               #saving as plain SVG gets rid of the classes :/
+               #cmd = "#{INKSCAPE} -f #{icon[:file]} -z --vacuum-defs -l #{icon[:file]} > /dev/null 2>&1"
+               #system(cmd)
+               svgcrop = Document.new(File.new(icon[:file], 'r'))
+               svgcrop.root.each_element("//rect") do |rect|
+                       w = ((rect.attributes["width"].to_f * 10).round / 10.0).to_i #get rid of 16 vs 
15.99999
+                       h = ((rect.attributes["width"].to_f * 10).round / 10.0).to_i #Inkscape bugs
+                       if w == 16 && h == 16
+                               rect.remove
+                       end
+               end
+    icon_f = File.new(icon[:file],'w+')
+    icon_f.puts svgcrop
+    icon_f.close
+       else
+               puts " -- #{icon[:name]} already exists"
+       end
+end #end of function
+
+def get_output_filename(d,n)
+  outfile = "#{d}/#{n}.svg"
+  return outfile
+end
+
+#main
+# Open SVG file.
+svg = Document.new(File.new(SRC, 'r'))
+
+if (ARGV[0].nil?) #render all SVGs
+  puts "Rendering from icons in #{SRC}"
+       # Go through every layer.
+       svg.root.each_element("/svg/g[@inkscape:groupmode='layer']") do |context|
+               context_name = context.attributes.get_attribute("inkscape:label").value
+               puts "Going through layer '" + context_name + "'"
+               context.each_element("g") do |icon|
+                       #puts "DEBUG #{icon.attributes.get_attribute('id')}"
+                       dir = "#{PREFIX}/#{context_name}"
+                       icon_name = icon.attributes.get_attribute("inkscape:label").value
+                       chopSVG({       :name => icon_name,
+                                                               :id => icon.attributes.get_attribute("id"),
+                                                               :dir => dir,
+                                                               :file => get_output_filename(dir, icon_name)})
+               end
+       end
+  puts "\nrendered all SVGs"
+else #only render the icons passed
+  icons = ARGV
+  ARGV.each do |icon_name|
+       icon = svg.root.elements["//g[@inkscape:label='#{icon_name}']"]
+       dir = "#{PREFIX}/#{icon.parent.attributes['inkscape:label']}"
+               chopSVG({       :name => icon_name,
+                                                       :id => icon.attributes["id"],
+                                                       :dir => dir,
+                                                       :file => get_output_filename(dir, icon_name),
+                                                       :forcerender => true})
+       end
+  puts "\nrendered #{ARGV.length} icons"
+end
diff --git a/plugins/color-picker/icons/viewmode/viewmode-list.svg 
b/plugins/color-picker/icons/viewmode/viewmode-list.svg
new file mode 100644
index 0000000..4b371cd
--- /dev/null
+++ b/plugins/color-picker/icons/viewmode/viewmode-list.svg
@@ -0,0 +1,31 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' 
sodipodi:docname='viewmode-list.svg' height='98' id='svg7384' 
xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' 
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' 
xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' 
version='1.1' inkscape:version='0.91 r13725' width='98' xmlns='http://www.w3.org/2000/svg'>
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='true' inkscape:bbox-paths='true' bordercolor='#666666' 
borderlayer='true' borderopacity='1' inkscape:current-layer='layer2' inkscape:cx='-179.32321' 
inkscape:cy='44.527328' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' 
inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#8ce0f0' 
inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' 
inkscape:showpageshadow='false' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' 
inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-nodes='false' 
inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='1043' 
inkscape:window-maximized='1' inkscape:window-width='1920' inkscape:window-x='0' inkscape:window-y='0' 
inkscape:zoom='1.5753505'>
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-401.30265' originy='-0.44884889' 
snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'/>
+  <g inkscape:groupmode='layer' id='layer3' inkscape:label='palette' 
transform='translate(-401.30265,82.448849)'/>
+  <g inkscape:groupmode='layer' id='layer2' inkscape:label='viewmode' 
transform='translate(-401.30265,0.44884889)'>
+    <rect height='95' id='rect4333' rx='3.8039246' ry='3.8039246' 
style='color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new'
 width='95' x='402.80264' y='1.0511512'/>
+    <rect height='15.026019' id='rect4337' rx='0' ry='0' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.59358287;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='73.826248' x='412.78964' y='31.266911'/>
+    <rect height='15.026019' id='rect4345' rx='0' ry='0' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.76470588;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='73.826248' x='412.78964' y='51.266911'/>
+    <rect height='15.026019' id='rect4353' rx='0' ry='0' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.36363639;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='73.826248' x='412.78964' y='71.266907'/>
+    <rect height='15.026019' id='rect4361' rx='0' ry='0' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='72.928543' x='413.83838' y='10.360477'/>
+    <rect height='0' id='rect4369' 
style='fill:#bdd2e9;fill-opacity:0.87165773;stroke-width:5;stroke-linecap:round' width='0' x='109.96993' 
y='-0.44884887'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer1' sodipodi:insensitive='true' inkscape:label='text' 
style='display:none' transform='translate(-401.30265,0.44884889)'>
+    <text id='text4208' sodipodi:linespacing='125%' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:&apos;Andale 
Mono&apos;;-inkscape-font-specification:&apos;Andale Mono, 
Normal&apos;;text-align:start;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:1px' x='-122' 
y='-94'><tspan id='tspan4212' sodipodi:role='line' x='-122' y='-94'/></text>
+    <flowRoot id='flowRoot4214' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4216'><rect height='52' id='rect4218' 
style='font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell,
 Normal&apos;;text-align:start;writing-mode:lr-tb;text-anchor:start' width='392' x='-350' 
y='-163'/></flowRegion><flowPara id='flowPara4220'/></flowRoot>    <flowRoot id='flowRoot4222' 
xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4224'><rect height='51' id='rect4226' width='401' x='-125' y='-207'/></
 flowRegion><flowPara id='flowPara4228'/></flowRoot>    <flowRoot id='flowRoot4230' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(184,-314.56579)'><flowRegion id='flowRegion4232'><rect height='39' id='rect4234' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4236' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>palettes</flowPara></flowRoot>    
<flowRoot id='flowRoot4238' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(232,-254.24079)'><flowRegion id='flowRegi
 on4240'><rect height='39' id='rect4242' width='153' x='-163' y='207'/></flowRegion><flowPara 
id='flowPara4244' style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>save</flowPara></flowRoot>    <flowRoot 
id='flowRoot4246' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(137,-254.21579)'><flowRegion id='flowRegion4248'><rect height='39' id='rect4250' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4252' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>load</flowPara></flowRoot>    <flowRoot 
id='flowRoot4358' xml:space='preserve' style='font-size:40px;line-heig
 ht:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(487,-314.56579)'><flowRegion id='flowRegion4360'><rect height='39' id='rect4362' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4364' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>view mode</flowPara></flowRoot>    
<flowRoot id='flowRoot4366' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(535,-254.24079)'><flowRegion id='flowRegion4368'><rect height='39' id='rect4370' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4372' style='font-size:25px;l
 ine-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>swatchs</flowPara></flowRoot>    
<flowRoot id='flowRoot4374' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(440,-254.21579)'><flowRegion id='flowRegion4376'><rect height='39' id='rect4378' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4380' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>list</flowPara></flowRoot>  </g>
+</svg>
diff --git a/plugins/color-picker/icons/viewmode/viewmode-swatchs.svg 
b/plugins/color-picker/icons/viewmode/viewmode-swatchs.svg
new file mode 100644
index 0000000..f965f26
--- /dev/null
+++ b/plugins/color-picker/icons/viewmode/viewmode-swatchs.svg
@@ -0,0 +1,43 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' 
sodipodi:docname='viewmode-swatchs.svg' height='98' id='svg7384' 
xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' 
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' 
xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' 
version='1.1' inkscape:version='0.91 r13725' width='98' xmlns='http://www.w3.org/2000/svg'>
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='true' inkscape:bbox-paths='true' bordercolor='#666666' 
borderlayer='true' borderopacity='1' inkscape:current-layer='layer2' inkscape:cx='-69.802166' 
inkscape:cy='44.527321' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' 
inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#8ce0f0' 
inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' 
inkscape:showpageshadow='false' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' 
inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-nodes='false' 
inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='1043' 
inkscape:window-maximized='1' inkscape:window-width='1920' inkscape:window-x='0' inkscape:window-y='0' 
inkscape:zoom='1.5753505'>
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-291.7816' originy='-0.44885666' 
snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'/>
+  <g inkscape:groupmode='layer' id='layer3' inkscape:label='palette' 
transform='translate(-291.7816,82.448857)'/>
+  <g inkscape:groupmode='layer' id='layer2' inkscape:label='viewmode' 
transform='translate(-291.7816,0.44885666)'>
+    <rect height='95' id='rect4260' rx='3.8039246' ry='3.8039246' 
style='color:#000000;overflow:visible;fill:#ffffff;stroke:#729fcf;stroke-width:3;marker:none;enable-background:new'
 width='95' x='293.28162' y='1.0511473'/>
+    <rect height='15.026019' id='rect4284' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.59358287;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='303.26859' y='31.266943'/>
+    <rect height='15.026019' id='rect4286' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.87165773;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='323.26859' y='31.266943'/>
+    <rect height='15.026019' id='rect4288' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.62566845;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='343.26859' y='31.266943'/>
+    <rect height='15.026019' id='rect4290' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='363.26859' y='31.266943'/>
+    <rect height='15.026019' id='rect4292' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.76470588;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='303.26859' y='51.266945'/>
+    <rect height='15.026019' id='rect4294' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.61497324;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='323.26859' y='51.266945'/>
+    <rect height='15.026019' id='rect4296' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='343.26859' y='51.266945'/>
+    <rect height='15.026019' id='rect4298' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.53475934;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='363.26859' y='51.266945'/>
+    <rect height='15.026019' id='rect4300' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.36363639;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='303.26859' y='71.266945'/>
+    <rect height='15.026019' id='rect4302' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='323.26859' y='71.266945'/>
+    <rect height='15.026019' id='rect4304' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.58823529;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='343.26859' y='71.266945'/>
+    <rect height='15.026019' id='rect4306' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='363.26859' y='71.266945'/>
+    <rect height='15.026019' id='rect4275' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='303.26859' y='10.809362'/>
+    <rect height='15.026019' id='rect4277' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.64171125;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='323.26859' y='10.809362'/>
+    <rect height='15.026019' id='rect4279' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.87700536;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='343.26859' y='10.809362'/>
+    <rect height='15.026019' id='rect4281' rx='1.2406625' ry='1.2406625' 
style='color:#000000;overflow:visible;color-interpolation-filters:linearRGB;solid-opacity:1;fill:#bdd2e9;fill-opacity:0.58288772;stroke-width:5;marker:none;marker-start:none;marker-mid:none;marker-end:none;image-rendering:auto;text-rendering:auto;enable-background:new'
 width='15.026019' x='363.26859' y='10.809362'/>
+    <rect height='0' id='rect4305' 
style='fill:#bdd2e9;fill-opacity:0.87165773;stroke-width:5;stroke-linecap:round' width='0' x='0.44887' 
y='-0.44883999'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer1' sodipodi:insensitive='true' inkscape:label='text' 
style='display:none' transform='translate(-291.7816,0.44885666)'>
+    <text id='text4208' sodipodi:linespacing='125%' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:&apos;Andale 
Mono&apos;;-inkscape-font-specification:&apos;Andale Mono, 
Normal&apos;;text-align:start;letter-spacing:0px;word-spacing:0px;fill:#000000;stroke-width:1px' x='-122' 
y='-94'><tspan id='tspan4212' sodipodi:role='line' x='-122' y='-94'/></text>
+    <flowRoot id='flowRoot4214' xml:space='preserve' 
style='font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4216'><rect height='52' id='rect4218' 
style='font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell,
 Normal&apos;;text-align:start;writing-mode:lr-tb;text-anchor:start' width='392' x='-350' 
y='-163'/></flowRegion><flowPara id='flowPara4220'/></flowRoot>    <flowRoot id='flowRoot4222' 
xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;stroke-width:1px'><flowRegion 
id='flowRegion4224'><rect height='51' id='rect4226' width='401' x='-125' y='-207'/></
 flowRegion><flowPara id='flowPara4228'/></flowRoot>    <flowRoot id='flowRoot4230' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(184,-314.56579)'><flowRegion id='flowRegion4232'><rect height='39' id='rect4234' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4236' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>palettes</flowPara></flowRoot>    
<flowRoot id='flowRoot4238' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(232,-254.24079)'><flowRegion id='flowRegi
 on4240'><rect height='39' id='rect4242' width='153' x='-163' y='207'/></flowRegion><flowPara 
id='flowPara4244' style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>save</flowPara></flowRoot>    <flowRoot 
id='flowRoot4246' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(137,-254.21579)'><flowRegion id='flowRegion4248'><rect height='39' id='rect4250' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4252' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>load</flowPara></flowRoot>    <flowRoot 
id='flowRoot4358' xml:space='preserve' style='font-size:40px;line-heig
 ht:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(487,-314.56579)'><flowRegion id='flowRegion4360'><rect height='39' id='rect4362' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4364' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>view mode</flowPara></flowRoot>    
<flowRoot id='flowRoot4366' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(535,-254.24079)'><flowRegion id='flowRegion4368'><rect height='39' id='rect4370' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4372' style='font-size:25px;l
 ine-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>swatchs</flowPara></flowRoot>    
<flowRoot id='flowRoot4374' xml:space='preserve' 
style='font-size:40px;line-height:125%;font-family:Cantarell;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:1px' 
transform='translate(440,-254.21579)'><flowRegion id='flowRegion4376'><rect height='39' id='rect4378' 
width='153' x='-163' y='207'/></flowRegion><flowPara id='flowPara4380' 
style='font-size:25px;line-height:125%;-inkscape-font-specification:&apos;Cantarell, 
Normal&apos;;text-align:center;writing-mode:lr-tb;text-anchor:middle'>list</flowPara></flowRoot>  </g>
+</svg>
diff --git a/plugins/color-picker/theme/Adwaita-dark.css b/plugins/color-picker/theme/Adwaita-dark.css
new file mode 100644
index 0000000..c73331a
--- /dev/null
+++ b/plugins/color-picker/theme/Adwaita-dark.css
@@ -0,0 +1,8 @@
+@import url("resource:///org/gnome/builder/plugins/color-picker-plugin/theme/Adwaita-shared.css");
+
+/* palettew widget dnd indicator */
+gstylecolorpanel gstylepalettewidget.dnd {
+  border-color: #4e9a06;
+  background-color: #4e9a06;
+}
+
diff --git a/plugins/color-picker/theme/Adwaita-shared.css b/plugins/color-picker/theme/Adwaita-shared.css
new file mode 100644
index 0000000..ff143a4
--- /dev/null
+++ b/plugins/color-picker/theme/Adwaita-shared.css
@@ -0,0 +1,326 @@
+/*
+ * Panel
+ */
+
+gstylecolorpanel {
+  font-size: 12px;
+}
+
+gstylecolorpanel > box {
+  border: solid alpha(@borders, 0.75);
+  border-width: 1px 0px 0px 0px;
+}
+
+#search_strings_popover gstylecolorwidget label,
+gstylecolorpanel gstylecolorwidget label,
+#colorpicker_preview_widget gstylecolorwidget label {
+  padding: 12px;
+}
+
+/* Buttons and Toggles - remove default style */
+gstylecolorpanel button.toggle,
+gstylecolorpanel #components_menu_button,
+gstylecolorpanel #strings_menu_button,
+gstylecolorpanel #components_controls,
+gstylecolorpanel #strings_controls,
+gstylecolorpanel #palette_controls {
+  background-image: none;
+  background: none;
+  outline-offset: -3px;
+  transition-duration: 200ms;
+  transition-timing-function: ease;
+}
+
+/* Reveal bars */
+gstylecolorpanel button.reveal-bar,
+gstylecolorpanel #components_controls,
+gstylecolorpanel #strings_controls,
+gstylecolorpanel #palette_controls {
+  margin: 0px;
+  padding: 0px;
+  background-color: @content_view_bg;
+  border: solid alpha(@borders, 0.75);
+  border-width: 0px 0px 1px 0px;
+  border-radius: 0px;
+}
+
+gstylecolorpanel button.reveal-bar label,
+gstylecolorpanel #components_controls label,
+gstylecolorpanel #strings_controls label,
+gstylecolorpanel #palette_controls label {
+  padding: 0px 10px;
+}
+
+gstylecolorpanel button.reveal-bar:checked {
+  box-shadow: 2px 1px 2px 0px alpha(@borders, 0.8);
+}
+
+/* Reveal bars reveal buttons */
+gstylecolorpanel #components_controls > button,
+gstylecolorpanel #strings_controls > button,
+gstylecolorpanel #palette_controls > button {
+  border:none;
+  padding: 0px;
+}
+
+gstylecolorpanel #components_menu_button,
+gstylecolorpanel #strings_menu_button {
+  min-width: 24px;
+  min-height: 24px;
+  }
+
+/* Components toggles */
+gstylecolorpanel #scale_box button.toggle
+{
+  background-color: @theme_base_color;
+  margin: 3px;
+  padding: 0px 6px;
+  border: solid 1px alpha(@borders, 0.75);
+  border-width: 2px;
+  border-radius: 0px;
+}
+
+gstylecolorpanel #scale_box button.toggle:checked {
+  background-color: @theme_bg_color;
+  border: solid 2px @theme_selected_bg_color;
+  box-shadow: inset 1px 1px 1px 0px alpha(@borders, 0.8);
+}
+
+/*
+ * Editor
+ */
+
+gstylecolorpanel #editor_grid
+{
+  margin: 3px;
+}
+
+gstylecolorpanel #swatchs_box gstylecolorwidget
+{
+  margin: 3px;
+}
+
+/* Picker Button */
+gstylecolorpanel #picker_button {
+  margin: 0px;
+  padding: 3px;
+}
+
+/* GstyleColorPlane */
+gstylecolorpanel gstylecolorplane,
+gstylecolorpanel gstylecolorscale contents {
+  border: solid 1px @theme_base_color;
+}
+
+/*
+ * Color Strings
+ */
+
+gstylecolorpanel #search_color_entry {
+  min-height: 24px;
+  border-radius: 0px;
+}
+
+gstylecolorpanel #string_grid {
+  margin: 6px 12px;
+}
+
+gstylecolorpanel label.selectable {
+  background-color: alpha(@theme_base_color, 0.8);
+  margin: 1px 0px 1px 6px;
+  padding: 0px 6px;
+}
+
+/*
+ * Color Components
+ */
+
+gstylecolorpanel #scale_box grid {
+  margin: 0px;
+  padding: 6px;
+}
+
+/* Components unit icon */
+gstylecolorpanel #scale_box spinbutton entry image {
+  padding: 0px;
+  -gtk-icon-transform: scale(0.7) translateX(6px);
+  -gtk-icon-shadow: 0 0 @theme_base_color;
+}
+gstylecolorpanel #scale_box spinbutton entry image:backdrop {
+ -gtk-icon-shadow: none;
+}
+
+gstylecolorpanel #scale_box spinbutton undershoot.right {
+  border: none;
+}
+
+/* Components Spin Buttons */
+gstylecolorpanel #scale_box spinbutton {
+  margin: 3px;
+  min-height: 26px;
+  border-radius: 0px;
+}
+
+gstylecolorpanel #scale_box spinbutton button {
+  padding: 3px;
+  -gtk-icon-transform: scale(0.8);
+}
+
+gstylecolorpanel #scale_box spinbutton entry {
+  min-height: 10px;
+  padding: 0px 0px 0px 3px;;
+}
+
+/* Components color scale */
+gstylecolorpanel gstylecolorscale {
+  margin: 3px;
+}
+
+/*
+ * Color Widget (swatchs)
+ */
+gstylecolorwidget label {
+  padding: 10px;
+}
+
+/*
+ * Prefs pages
+ */
+gstyleslidein > stack {
+  background-color: @theme_bg_color;
+  border: solid alpha(@borders, 0.2);
+  border-width: 0px 1px 0px 0px;
+}
+
+gstylecolorpanel #components_prefs_button:checked,
+gstylecolorpanel #color_strings_prefs_button:checked,
+gstylecolorpanel #palettes_prefs_button:checked,
+gstylecolorpanel #palettes_list_prefs_button:checked {
+  color: alpha(@theme_selected_bg_color, 0.9);
+}
+
+gstyleslidein label.cp-prefs-grouptitle {
+  margin: 12px 0px 6px 0px;
+}
+
+gstyleslidein label.cp-prefs-resume {
+  background-color: @insensitive_bg_color;
+  border: 1px solid alpha(@borders, 0.4);
+  margin: 0px 0px 6px 0px;
+  padding: 12px;
+}
+
+gstyleslidein gbcolorpickerprefslist,
+gstyleslidein gbcolorpickerprefspalettelist {
+  border: 1px solid @borders;
+  background-color: @theme_base_color;
+}
+
+gstyleslidein gbcolorpickerprefslist row,
+gstyleslidein gbcolorpickerprefspalettelist row {
+  border-bottom: 1px solid alpha(@borders, 0.2);
+  padding: 10px;
+}
+
+gstyleslidein gbcolorpickerprefslist row:last-child,
+gstyleslidein gbcolorpickerprefspalettelist row:last-child {
+  border-bottom: none;
+}
+
+gstyleslidein gbcolorpickerprefslist button ,
+gstyleslidein gbcolorpickerprefspalettelist button {
+  background: none;
+  box-shadow: none;
+}
+
+gstyleslidein gbcolorpickerprefspalettelist > button {
+  border-width: 0px 0px 1px 0px;
+  border-color: alpha(@borders, 0.2);
+}
+
+gstyleslidein gbcolorpickerprefslist row button,
+gstyleslidein gbcolorpickerprefspalettelist row button {
+  border: solid 2px alpha (@theme_selected_bg_color, 0);
+}
+
+gstyleslidein gbcolorpickerprefslist row button:hover,
+gstyleslidein gbcolorpickerprefspalettelist row button:hover {
+  background: none;
+  box-shadow: none;
+  border: solid 2px @theme_selected_bg_color;
+}
+
+gstyleslidein #load_palette_button,
+gstyleslidein #save_palette_button {
+  background: none;
+  border: none;
+  outline-offset: 0px;
+  padding: 6px;
+}
+
+/*
+ * Palettes
+ */
+
+gstylecolorpanel gstylepalettewidget list {
+  background: none;
+  margin: 4px 3px;
+}
+
+gstylecolorpanel gstylepalettewidget flowbox {
+  background: none;
+  margin: 2px;
+}
+
+gstylecolorpanel gstylepalettewidget stack {
+  background: @theme_unfocused_bg_color;
+  box-shadow: 1px 1px 3px alpha(@borders, 0.4) inset;
+  margin: 0px 3px 3px 3px;
+}
+
+gstylecolorpanel gstylepalettewidget > box > scrolledwindow {
+  border:  solid @borders;
+  border-width: 0px 1px 1px 1px;
+}
+
+gstylecolorpanel gstylepalettewidget gstylecolorwidget {
+  border: solid 1px alpha(@borders, 0.8);
+}
+
+/*
+ * FileChooserDialog preview
+ */
+
+#colorpicker_preview_title {
+  padding: 16px;
+}
+
+#colorpicker_preview_widget {
+  padding: 12px;
+  min-width: 400px;
+}
+
+/*
+ * Search color entry popover
+ */
+
+#search_strings_popover {
+  padding: 0px;
+}
+
+#search_strings_popover gstylecolorwidget {
+  border: solid 1px alpha(@borders, 0.8);
+}
+
+#search_strings_popover list {
+  background: none;
+  margin: 0px;
+}
+
+#search_strings_popover row {
+  padding: 2px;
+}
+
+#search_strings_popover scrolledwindow {
+  margin: 3px;
+}
diff --git a/plugins/color-picker/theme/Adwaita.css b/plugins/color-picker/theme/Adwaita.css
new file mode 100644
index 0000000..0a36987
--- /dev/null
+++ b/plugins/color-picker/theme/Adwaita.css
@@ -0,0 +1,10 @@
+@import url("resource:///org/gnome/builder/plugins/color-picker-plugin/theme/Adwaita-shared.css");
+
+/*
+ * FileChooserDialog preview
+ */
+
+gstylecolorpanel gstylepalettewidget.dnd {
+  border-color: #4e9a06;
+  background-color: #4e9a06;
+}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 98798a6..012d2e9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -102,6 +102,13 @@ plugins/clang/ide-clang-preferences-addin.c
 plugins/clang/ide-clang-service.c
 plugins/clang/ide-clang-symbol-node.c
 plugins/clang/ide-clang-translation-unit.c
+plugins/color-picker/color_picker_plugin/__init__.py
+plugins/color-picker/color_picker_plugin/io.py
+plugins/color-picker/color_picker_plugin/ui.py
+plugins/color-picker/color_picker_plugin/data/basic.xml
+[type: gettext/glade]plugins/color-picker/color_picker_plugin/gtk/color-picker.ui
+[type: gettext/glade]plugins/color-picker/color_picker_plugin/gtk/color-picker-preview.ui
+[type: gettext/glade]plugins/color-picker/color_picker_plugin/gtk/menus.ui
 plugins/command-bar/gb-command-bar.c
 plugins/command-bar/gb-vim.c
 [type: gettext/glade]plugins/comment-code/gtk/menus.ui



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]