HTMLify
Color Picker
Views: 10 | Author: abh
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkevents.h>
#include <stdio.h>
// main color
unsigned char R = 255, G = 0, B = 0;
unsigned char s_r = 255, s_g = 0, s_b = 0;
int H; // Hue
void update_color(unsigned char r, unsigned char g, unsigned char b) {
R = r, G = g, B = b;
// gtk_scale_set_digits(GTK_SCALE(r_scale), 6);
}
void hue_to_RGB(int H, guchar *R, guchar *G, guchar *B) {
}
void HSV_to_RGB(int H, int S, int V, guchar *R, guchar *G, guchar *B) {
}
void color_for(int x, int y, const unsigned char base_r, const unsigned char base_g, const unsigned char base_b, guchar *r, guchar *g, guchar *b) {
double
s = (double)x/256,
v = (double)y/256
;
int e;
if (s < 0) s = 0;
if (s > 1) s = 1;
if (v < 0) v = 0;
if (v > 1) v = 1;
e = (int)((-s+v)*255);
if (base_r + e > 255)
*r = 255;
else if (base_r + e < 0)
*r = 0;
else
*r = base_r + e;
if (base_g + e > 255)
*g = 255;
else if (base_g + e < 0)
*g = 0;
else
*g = base_g + e;
if (base_b + e > 255)
*b = 255;
else if (base_b + e < 0)
*b = 0;
else
*b = base_b + e;
}
void fill_color_grid(GdkPixbuf *grid, const unsigned char base_r, const unsigned char base_g, const unsigned char base_b) {
int w = 256, h = 256, i, j, k, rs, n_c;
guchar *pixel, *pixels = gdk_pixbuf_get_pixels(grid);
guchar r, g, b;
rs = gdk_pixbuf_get_rowstride(grid);
n_c = gdk_pixbuf_get_n_channels(grid);
for (i=0; i<h; i++) {
for (j=0; j<w; j++) {
pixel = pixels + i*rs + j*n_c;
color_for(j, i, base_r, base_g, base_b, &r, &g, &b);
pixel[0] = r;//%256;//base_r + (i*2);
pixel[1] = g;//%256;//base_g + (j);
pixel[2] = b;//%256;//base_b + (j);
}
}
}
void fill_select_color_grid(GdkPixbuf *grid) {
int w = 90, h = 30, i, j, rs, n_c;
guchar *pixel, *pixels = gdk_pixbuf_get_pixels(grid);
rs = gdk_pixbuf_get_rowstride(grid);
n_c = gdk_pixbuf_get_n_channels(grid);
for (i=0; i<h; i++) {
for (j=0; j<w; j++) {
pixel = pixels + i*rs + j*n_c;
pixel[0] = s_r;
pixel[1] = s_g;
pixel[2] = s_b;
}
}
}
gboolean auto_update_color_grid(gpointer image_p) {
GdkPixbuf *color_grid = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, 256, 256);
GtkWidget *image = GTK_WIDGET(image_p);
fill_color_grid(color_grid, R, G, B);
gtk_image_set_from_pixbuf(GTK_IMAGE(image), color_grid);
return TRUE;
}
gboolean auto_update_select_color(gpointer image_p) {
GdkPixbuf *color_grid = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, 90, 30);
GtkWidget *image = GTK_WIDGET(image_p);
fill_select_color_grid(color_grid);
gtk_image_set_from_pixbuf(GTK_IMAGE(image), color_grid);
return TRUE;
}
gboolean auto_sync_selected_color(gpointer elements) {
GPtrArray *array = elements;
GtkRange
*r_scale = g_ptr_array_index(array, 0),
*g_scale = g_ptr_array_index(array, 1),
*b_scale = g_ptr_array_index(array, 2)
;
GtkEditable
*r_entry = g_ptr_array_index(array, 3),
*g_entry = g_ptr_array_index(array, 4),
*b_entry = g_ptr_array_index(array, 5),
*html_notation_entry = g_ptr_array_index(array, 6)
;
char buf[10];
gtk_range_set_value(r_scale, (double)s_r);
gtk_range_set_value(g_scale, (double)s_g);
gtk_range_set_value(b_scale, (double)s_b);
sprintf(buf, "%.2f", (double)s_r);
gtk_editable_set_text(r_entry, buf);
sprintf(buf, "%.2f", (double)s_g);
gtk_editable_set_text(g_entry, buf);
sprintf(buf, "%.2f", (double)s_b);
gtk_editable_set_text(b_entry, buf);
sprintf(buf, "#%02X%02X%02X", s_r, s_g, s_b);
gtk_editable_set_text(html_notation_entry, buf);
return TRUE;
}
void on_color_select(GtkGestureClick *gesture, int n_p, double x, double y, GtkWidget *color_grid) {
// g_print("click detected on x: %f y: %f \n", x, y);
// GtkAllocation alloc;
// int cx, cy;
// gtk_widget_get_allocation(color_grid, &alloc);
// cx = ((x - alloc.x)/alloc.width)*255;
// cy = ((y - alloc.y)/alloc.height)*255;
color_for(x, y, R, G, B, &s_r, &s_g, &s_b);
// g_print("calculated cx: %d, yx: %d\n", cx, cy);
}
void on_color_bar_scale_change(GtkRange *scale, gpointer *image) {
unsigned char r = 255, g = 0, b = 0;
int value = gtk_range_get_value(GTK_RANGE(scale));
if (value && value >= 256) {
b += 255;
value -= 256;
} else if (value) {
b += value-1;
value = 0;
}
if (value && value >= 256) {
r -= 255;
value -= 256;
} else if (value) {
r -= value-1;
value = 0;
}
if (value && value >= 256) {
g += 255;
value -= 256;
} else if (value) {
g += value-1;
value = 0;
}
if (value && value >= 256) {
b -= 255;
value -= 256;
} else if (value) {
b -= value-1;
value = 0;
}
if (value && value >= 256) {
r += 255;
value -= 256;
} else if (value) {
r -= value-1;
value = 0;
}
if (value && value >= 256) {
g -= 255;
value -= 256;
} else if (value) {
g -= value-1;
value = 0;
}
R = r, G = g, B = b;
s_r = r, s_g = g, s_b = b;
}
void on_color_scale_change(GtkRange *scale, gpointer *entry) {
double value = gtk_range_get_value(scale);
char c = gtk_widget_get_name(GTK_WIDGET(scale))[0];
switch (c) {
case 'r':
s_r = (guchar)value;
break;
case 'g':
s_g = (guchar)value;
break;
case 'b':
s_b = (guchar)value;
break;
}
}
void on_color_entry_activate(GtkEditable *entry, GtkRange *scale) {
const char *text = gtk_editable_get_text(entry);
float value;
int i=0;
bool is_num=true;
while (text[i] != '\0') {
if (text[i] < '0' || text[i] > '9') {
is_num = false;
break;
}
i++;
}
if (is_num) {
char c = gtk_widget_get_name(GTK_WIDGET(entry))[0];
switch (c) {
case 'r':
s_r = (guchar)value; break;
case 'g':
s_g = (guchar)value; break;
case 'b':
s_b = (guchar)value; break;
}
}
}
void on_app_activate(GtkApplication *app, gpointer null_value) {
GtkWidget
*window = gtk_application_window_new(app),
*master_div = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2),
*left_pane = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2),
*color_grid_image = gtk_image_new(),
*color_bar = gtk_scale_new_with_range(GTK_ORIENTATION_VERTICAL, 1, 256*6, 1),
*right_pane = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1),
*r_pack_div = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3),
*g_pack_div = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3),
*b_pack_div = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3),
*r_label = gtk_label_new("R"),
*g_label = gtk_label_new("G"),
*b_label = gtk_label_new("B"),
*r_scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 255, 1),
*g_scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 255, 1),
*b_scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 255, 1),
*r_entry = gtk_entry_new(),
*g_entry = gtk_entry_new(),
*b_entry = gtk_entry_new(),
*html_notation_pack_div = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3),
*selected_color_image = gtk_image_new(),
*html_notation_label = gtk_label_new("HTML Notation:"),
*html_notation_entry = gtk_entry_new()
;
GtkEventController *click = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
GdkPixbuf *color_grid = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, 256, 256);
GdkPixbuf *s_color_grid = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false, 8, 90, 30);
// left pane packing
gtk_widget_set_valign(color_grid_image, GTK_ALIGN_START);
gtk_widget_set_halign(color_grid_image, GTK_ALIGN_START);
gtk_widget_set_size_request(color_grid_image, 256, 256);
gtk_widget_set_hexpand(color_grid_image, true);
gtk_widget_set_name(color_bar, "color-bar");
gtk_box_append(GTK_BOX(left_pane), color_grid_image);
gtk_box_append(GTK_BOX(left_pane), color_bar);
// right pane packing
gtk_widget_set_hexpand(r_scale, true);
gtk_widget_set_hexpand(g_scale, true);
gtk_widget_set_hexpand(b_scale, true);
gtk_widget_set_name(r_scale, "r-scale");
gtk_widget_set_name(g_scale, "g-scale");
gtk_widget_set_name(b_scale, "b-scale");
gtk_widget_set_name(r_entry, "r-ently");
gtk_widget_set_name(g_entry, "g-ently");
gtk_widget_set_name(b_entry, "b-ently");
gtk_box_append(GTK_BOX(r_pack_div), r_label);
gtk_box_append(GTK_BOX(r_pack_div), r_scale);
gtk_box_append(GTK_BOX(r_pack_div), r_entry);
gtk_box_append(GTK_BOX(g_pack_div), g_label);
gtk_box_append(GTK_BOX(g_pack_div), g_scale);
gtk_box_append(GTK_BOX(g_pack_div), g_entry);
gtk_box_append(GTK_BOX(b_pack_div), b_label);
gtk_box_append(GTK_BOX(b_pack_div), b_scale);
gtk_box_append(GTK_BOX(b_pack_div), b_entry);
gtk_box_append(GTK_BOX(right_pane), r_pack_div);
gtk_box_append(GTK_BOX(right_pane), g_pack_div);
gtk_box_append(GTK_BOX(right_pane), b_pack_div);
gtk_widget_set_size_request(selected_color_image, 90, 60);
gtk_widget_set_hexpand(selected_color_image, true);
// gtk_widget_set_vexpand(selected_color_image, true);
gtk_editable_set_editable(GTK_EDITABLE(html_notation_entry), false);
gtk_box_append(GTK_BOX(html_notation_pack_div), selected_color_image);
gtk_box_append(GTK_BOX(html_notation_pack_div), html_notation_label);
gtk_box_append(GTK_BOX(html_notation_pack_div), html_notation_entry);
gtk_box_append(GTK_BOX(right_pane), html_notation_pack_div);
// master div packing
gtk_box_append(GTK_BOX(master_div), left_pane);
gtk_box_append(GTK_BOX(master_div), right_pane);
// signals
g_signal_connect(click, "pressed", G_CALLBACK(on_color_select), color_grid_image);
g_signal_connect(color_bar, "value-changed", G_CALLBACK(on_color_bar_scale_change), color_grid_image);
g_signal_connect(r_scale, "value-changed", G_CALLBACK(on_color_scale_change), r_entry);
g_signal_connect(g_scale, "value-changed", G_CALLBACK(on_color_scale_change), g_entry);
g_signal_connect(b_scale, "value-changed", G_CALLBACK(on_color_scale_change), b_entry);
g_signal_connect(r_entry, "activate", G_CALLBACK(on_color_entry_activate), r_scale);
g_signal_connect(g_entry, "activate", G_CALLBACK(on_color_entry_activate), g_scale);
g_signal_connect(b_entry, "activate", G_CALLBACK(on_color_entry_activate), b_scale);
gtk_widget_add_controller(color_grid_image, click);
GPtrArray *elements = g_ptr_array_new();
g_ptr_array_add(elements, r_scale);
g_ptr_array_add(elements, g_scale);
g_ptr_array_add(elements, b_scale);
g_ptr_array_add(elements, r_entry);
g_ptr_array_add(elements, g_entry);
g_ptr_array_add(elements, b_entry);
g_ptr_array_add(elements, html_notation_entry);
g_timeout_add_seconds(1/5, auto_update_color_grid, color_grid_image);
g_timeout_add_seconds(1/5, auto_update_select_color, selected_color_image);
g_timeout_add_seconds(1/5, auto_sync_selected_color, elements);
// main window
gtk_window_set_child(GTK_WINDOW(window), master_div);
gtk_window_set_default_size(GTK_WINDOW(window), 650, 300);
gtk_widget_set_visible(window, true);
// CSS Provider
GtkCssProvider *provider = gtk_css_provider_new();
gtk_css_provider_load_from_data(provider,
"#color-bar {"
" background-image: linear-gradient(#ff0000, #ff00ff, #0000ff, #00ffff, #00ff00, #ffff00, #ff0000);"
"}"
"#color-bar slider {"
" opacity: 0;"
"}"
, -1);
// Apply CSS to screen
GtkStyleContext *context;
context = gtk_widget_get_style_context(window);
gtk_style_context_add_provider_for_display(
gdk_display_get_default(),
GTK_STYLE_PROVIDER(provider),
GTK_STYLE_PROVIDER_PRIORITY_USER
);
}
int main(int argc, char **argv) {
GtkApplication *app = gtk_application_new("sir.kk.for.color-picker", 0);
g_signal_connect(app, "activate", G_CALLBACK(on_app_activate), NULL);
return g_application_run(G_APPLICATION(app), argc, argv);
}