/* * JoeyDev * Copyright (C) 2018-2023 Scott Duensing * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. */ #include "common.h" #include "palette.h" typedef struct PaletteDialogDataS { GtkWidget *drawingArea; GtkAdjustment *adjustmentRed; GtkAdjustment *adjustmentGreen; GtkAdjustment *adjustmentBlue; GtkWidget *scaleRed; GtkWidget *scaleGreen; GtkWidget *scaleBlue; } PaletteDialogDataT; EVENT gboolean paletteDialogClose(GtkWidget *widget, GdkEvent *event, gpointer userData); EVENT gboolean paletteDialogDraw(GtkWidget *widget, cairo_t *cr, gpointer userData); EVENT void paletteValueChanged(GtkRange *widget, gpointer userData); EVENT gboolean paletteDialogClose(GtkWidget *widget, GdkEvent *event, gpointer userData) { PaletteDialogDataT *self = g_object_get_data(G_OBJECT(widget), "paletteData"); (void)event; (void)userData; DEL(self); return FALSE; } EVENT gboolean paletteDialogDraw(GtkWidget *widget, cairo_t *cr, gpointer userData) { PaletteDialogDataT *self = (PaletteDialogDataT *)userData; double scale = 1.0/16.0; double r; double g; double b; (void)widget; r = gtk_adjustment_get_value(self->adjustmentRed); g = gtk_adjustment_get_value(self->adjustmentGreen); b = gtk_adjustment_get_value(self->adjustmentBlue); cairo_set_source_rgb(cr, r * scale, g * scale, b * scale); cairo_paint(cr); return FALSE; } EVENT void paletteValueChanged(GtkRange *widget, gpointer userData) { PaletteDialogDataT *self = (PaletteDialogDataT *)userData; (void)widget; // Refresh widget. gtk_widget_queue_draw(self->drawingArea); } void palette_dialog_get_color(GtkWidget *paletteDialog, unsigned char *r, unsigned char *g, unsigned char *b) { PaletteDialogDataT *self = g_object_get_data(G_OBJECT(paletteDialog), "paletteData"); *r = (int)gtk_adjustment_get_value(self->adjustmentRed); *g = (int)gtk_adjustment_get_value(self->adjustmentGreen); *b = (int)gtk_adjustment_get_value(self->adjustmentBlue); } GtkWidget *palette_dialog_new(GtkWidget *parent, char *title, unsigned char r, unsigned char g, unsigned char b) { GtkWidget *dialog; GtkWidget *contentArea; PaletteDialogDataT *self; GtkWidget *vbox; GtkWidget *grid; GtkWidget *labelRed; GtkWidget *labelGreen; GtkWidget *labelBlue; self = NEW(PaletteDialogDataT); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_set_spacing(GTK_BOX(vbox), 10); self->drawingArea = gtk_drawing_area_new(); gtk_widget_set_size_request(self->drawingArea, 128, 64); g_signal_connect(G_OBJECT(self->drawingArea), "draw", G_CALLBACK(paletteDialogDraw), self); grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 10); gtk_grid_set_row_spacing(GTK_GRID(grid), 10); labelRed = gtk_label_new("Red:"); labelGreen = gtk_label_new("Green:"); labelBlue = gtk_label_new("Blue:"); gtk_widget_set_halign(labelRed, GTK_ALIGN_END); gtk_widget_set_halign(labelGreen, GTK_ALIGN_END); gtk_widget_set_halign(labelBlue, GTK_ALIGN_END); self->adjustmentRed = gtk_adjustment_new((double)r, 0.0, 15.0, 1.0, 4.0, 0.00); self->adjustmentGreen = gtk_adjustment_new((double)g, 0.0, 15.0, 1.0, 4.0, 0.00); self->adjustmentBlue = gtk_adjustment_new((double)b, 0.0, 15.0, 1.0, 4.0, 0.00); self->scaleRed = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, self->adjustmentRed); self->scaleGreen = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, self->adjustmentGreen); self->scaleBlue = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, self->adjustmentBlue); gtk_scale_set_draw_value(GTK_SCALE(self->scaleRed), FALSE); gtk_scale_set_draw_value(GTK_SCALE(self->scaleGreen), FALSE); gtk_scale_set_draw_value(GTK_SCALE(self->scaleBlue), FALSE); gtk_range_set_round_digits(GTK_RANGE(self->scaleRed), 0); gtk_range_set_round_digits(GTK_RANGE(self->scaleGreen), 0); gtk_range_set_round_digits(GTK_RANGE(self->scaleBlue), 0); gtk_widget_set_hexpand(self->scaleRed, TRUE); gtk_widget_set_hexpand(self->scaleGreen, TRUE); gtk_widget_set_hexpand(self->scaleBlue, TRUE); g_signal_connect(G_OBJECT(self->scaleRed), "value-changed", G_CALLBACK(paletteValueChanged), self); g_signal_connect(G_OBJECT(self->scaleGreen), "value-changed", G_CALLBACK(paletteValueChanged), self); g_signal_connect(G_OBJECT(self->scaleBlue), "value-changed", G_CALLBACK(paletteValueChanged), self); dialog = gtk_dialog_new_with_buttons( title, GTK_WINDOW(parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "_Cancel", GTK_RESPONSE_CANCEL, "_Select", GTK_RESPONSE_OK, NULL ); g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(paletteDialogClose), self); g_object_set_data(G_OBJECT(dialog), "paletteData", self); contentArea = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_grid_attach(GTK_GRID(grid), labelRed, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(grid), labelGreen, 0, 1, 1, 1); gtk_grid_attach(GTK_GRID(grid), labelBlue, 0, 2, 1, 1); gtk_grid_attach(GTK_GRID(grid), self->scaleRed, 1, 0, 1, 1); gtk_grid_attach(GTK_GRID(grid), self->scaleGreen, 1, 1, 1, 1); gtk_grid_attach(GTK_GRID(grid), self->scaleBlue, 1, 2, 1, 1); gtk_container_add(GTK_CONTAINER(vbox), self->drawingArea); gtk_container_add(GTK_CONTAINER(vbox), grid); gtk_container_add(GTK_CONTAINER(contentArea), vbox); gtk_widget_show_all(dialog); return dialog; }