Commit c0bfcb9c authored by Sébastien Lafargue's avatar Sébastien Lafargue Committed by Christian Hergert
Browse files

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.
parent ab5b98b6
......@@ -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}"
......
......@@ -4,6 +4,7 @@ SUBDIRS = \
build-tools \
c-pack \
clang \
color-picker \
command-bar \
comment-code \
contributing \
......
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
#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.
[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
# --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])
<?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>
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)
/* 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);