Color selection working! Palette is next.
This commit is contained in:
parent
999d0a6f6a
commit
511bf72427
4 changed files with 244 additions and 66 deletions
|
@ -26,16 +26,17 @@ project(joeydev C)
|
|||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
set(SOURCE_FILES
|
||||
src/main.c
|
||||
src/utils.c
|
||||
src/joeydev.c
|
||||
src/vector.c
|
||||
src/array.c
|
||||
src/draw.c
|
||||
src/image.c
|
||||
src/vecparse.c
|
||||
ui/generated/resources.c
|
||||
thirdparty/memwatch/memwatch.c
|
||||
thirdparty/memwatch/memwatch.c
|
||||
ui/generated/resources.c
|
||||
src/main.c
|
||||
src/utils.c
|
||||
src/joeydev.c
|
||||
src/vector.c
|
||||
src/array.c
|
||||
src/draw.c
|
||||
src/image.c
|
||||
src/vecparse.c
|
||||
src/color.c
|
||||
)
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES})
|
||||
|
|
137
src/color.c
Normal file
137
src/color.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* JoeyDev
|
||||
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||
*
|
||||
* 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 "color.h"
|
||||
|
||||
|
||||
typedef struct ColorDialogDataS {
|
||||
GtkWidget *buttons[16];
|
||||
int selected;
|
||||
} ColorDialogDataT;
|
||||
|
||||
|
||||
static void addCss(GtkWidget *widget, char *css);
|
||||
EVENT void colorClicked(GtkButton *widget, gpointer userData);
|
||||
EVENT gboolean colorDialogClose(GtkWidget *object, GdkEvent *event, gpointer userData);
|
||||
|
||||
|
||||
static void addCss(GtkWidget *widget, char *css) {
|
||||
GtkCssProvider *provider;
|
||||
GtkStyleContext *context;
|
||||
|
||||
provider = gtk_css_provider_new();
|
||||
gtk_css_provider_load_from_data(provider, css, -1,NULL);
|
||||
context = gtk_widget_get_style_context(widget);
|
||||
gtk_style_context_add_provider(context, GTK_STYLE_PROVIDER(provider),GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
g_object_unref(provider);
|
||||
}
|
||||
|
||||
|
||||
EVENT void colorClicked(GtkButton *widget, gpointer userData) {
|
||||
ColorDialogDataT *self = (ColorDialogDataT *)userData;
|
||||
int i;
|
||||
char *borderOn = "* { border-width: 3px; border-color: white; }";
|
||||
char *borderOff = "* { border-width: 0px; }";
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
if (widget == GTK_BUTTON(self->buttons[i])) {
|
||||
if (self->selected >= 0) {
|
||||
addCss(self->buttons[self->selected], borderOff);
|
||||
}
|
||||
self->selected = i;
|
||||
addCss(self->buttons[self->selected], borderOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EVENT gboolean colorDialogClose(GtkWidget *object, GdkEvent *event, gpointer userData) {
|
||||
ColorDialogDataT *self = g_object_get_data(G_OBJECT(object), "colorData");
|
||||
|
||||
(void)event;
|
||||
(void)userData;
|
||||
|
||||
DEL(self);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int color_dialog_get_selected(GtkWidget *colorDialog) {
|
||||
ColorDialogDataT *self = g_object_get_data(G_OBJECT(colorDialog), "colorData");
|
||||
|
||||
return self->selected;
|
||||
}
|
||||
|
||||
|
||||
GtkWidget *color_dialog_new(GtkWidget *parent, ColorT colors[]) {
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *contentArea;
|
||||
GtkWidget *grid;
|
||||
char temp[256];
|
||||
int x;
|
||||
int y;
|
||||
int i;
|
||||
ColorDialogDataT *self;
|
||||
|
||||
self = NEW(ColorDialogDataT);
|
||||
self->selected = -1;
|
||||
|
||||
grid = gtk_grid_new();
|
||||
gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
|
||||
gtk_grid_set_row_homogeneous(GTK_GRID(grid), TRUE);
|
||||
i = 0;
|
||||
for (y=0; y<4; y++) {
|
||||
for (x=0; x<4; x++) {
|
||||
self->buttons[i] = gtk_button_new();
|
||||
gtk_widget_set_hexpand(self->buttons[i], TRUE);
|
||||
gtk_widget_set_vexpand(self->buttons[i], TRUE);
|
||||
g_signal_connect(G_OBJECT(self->buttons[i]), "clicked", G_CALLBACK(colorClicked), self);
|
||||
snprintf(temp, 256, "* { background-image:none; background-color: #%02x%02x%02x; }", colors[i].red, colors[i].green, colors[i].blue);
|
||||
addCss(self->buttons[i], temp);
|
||||
gtk_grid_attach(GTK_GRID (grid), self->buttons[i], x, y, 1, 1);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons("Color",
|
||||
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(colorDialogClose), self);
|
||||
g_object_set_data(G_OBJECT(dialog), "colorData", self);
|
||||
gtk_widget_set_size_request(dialog, 320, 320);
|
||||
contentArea = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
|
||||
gtk_container_add(GTK_CONTAINER(contentArea), grid);
|
||||
|
||||
gtk_widget_show_all(dialog);
|
||||
|
||||
return dialog;
|
||||
}
|
41
src/color.h
Normal file
41
src/color.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* JoeyDev
|
||||
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
typedef struct ColorS {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
} ColorT;
|
||||
|
||||
|
||||
int color_dialog_get_selected(GtkWidget *colorDialog);
|
||||
GtkWidget *color_dialog_new(GtkWidget *parent, ColorT colors[]);
|
||||
|
||||
|
||||
#endif //COLOR_H
|
111
src/vector.c
111
src/vector.c
|
@ -34,6 +34,7 @@
|
|||
#include "draw.h"
|
||||
#include "image.h"
|
||||
#include "vecparse.h"
|
||||
#include "color.h"
|
||||
|
||||
|
||||
#define VICTOR_VERSION "1.00"
|
||||
|
@ -105,6 +106,7 @@ EVENT gboolean drawVectorImageDraw(GtkWidget *widget, cairo_t *cr, gpointer use
|
|||
EVENT gboolean drawVectorImageMotionEvent(GtkWidget *widget, GdkEventMotion *event, gpointer userData);
|
||||
EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotification *notifyData, gpointer userData);
|
||||
EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData);
|
||||
static int findClosestPoint(VectorDataT *self, int x, int y);
|
||||
static int getWord(VecByteCodeT *bytecode, int *index);
|
||||
static void insertCommand(VectorDataT *self, char *command);
|
||||
static void insertText(VectorDataT *self, char *text);
|
||||
|
@ -181,7 +183,8 @@ EVENT void drawVectorImageClick(GtkWidget *object, GdkEventButton *event, gpoint
|
|||
|
||||
switch (self->clickState) {
|
||||
case CLICK_NONE:
|
||||
// Do nothing.
|
||||
// Highlight the closest point in editor.
|
||||
findClosestPoint(self, x, y);
|
||||
break;
|
||||
|
||||
case CLICK_BOX_1:
|
||||
|
@ -340,12 +343,9 @@ EVENT gboolean drawVectorImageDraw(GtkWidget *widget, cairo_t *cr, gpointer user
|
|||
|
||||
EVENT gboolean drawVectorImageMotionEvent(GtkWidget *widget, GdkEventMotion *event, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
int closest = -1;
|
||||
int distance = INT_MAX;
|
||||
int x = (int)(event->x * 0.5);
|
||||
int y = (int)(event->y * 0.5);
|
||||
int temp;
|
||||
int i;
|
||||
char buffer[8];
|
||||
|
||||
// If we're in a drawing action, bail out of this.
|
||||
|
@ -354,34 +354,16 @@ EVENT gboolean drawVectorImageMotionEvent(GtkWidget *widget, GdkEventMotion *eve
|
|||
// If they're holding the button down, update the point.
|
||||
if (event->state & GDK_BUTTON1_MASK) {
|
||||
|
||||
// Find closest point to mouse pointer.
|
||||
for (i = 0; i < arrlen(self->pointList); i++) {
|
||||
temp = sqrt(pow(x - self->pointList[i]->x, 2) + pow(y - self->pointList[i]->y, 2));
|
||||
if (temp < distance) {
|
||||
closest = i;
|
||||
distance = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Did we find a point to edit?
|
||||
if (closest >= 0) {
|
||||
// Select first occurrence of it in the text editor.
|
||||
snprintf(buffer, 8, "%d,%d", self->pointList[closest]->x, self->pointList[closest]->y);
|
||||
SSM(SCI_TARGETWHOLEDOCUMENT, 0, 0);
|
||||
SSM(SCI_SETSEARCHFLAGS, SCFIND_NONE, 0);
|
||||
temp = SSM(SCI_SEARCHINTARGET, strlen(buffer), (sptr_t)buffer);
|
||||
// Did we find it in the text?
|
||||
if (temp >= 0) {
|
||||
// Select the text.
|
||||
SSM(SCI_SETSEL, temp, temp + strlen(buffer));
|
||||
// Are these values sane?
|
||||
if (x < 0) x = 0;
|
||||
if (x > 319) x = 319;
|
||||
if (y < 0) y = 0;
|
||||
if (y > 199) y = 199;
|
||||
snprintf(buffer, 8, "%d,%d", x, y);
|
||||
SSM(SCI_REPLACETARGET, -1, (sptr_t)buffer);
|
||||
}
|
||||
// Did we find it in the text?
|
||||
temp = findClosestPoint(self, x, y);
|
||||
if (temp >= 0) {
|
||||
// Are these values sane?
|
||||
if (x < 0) x = 0;
|
||||
if (x > 319) x = 319;
|
||||
if (y < 0) y = 0;
|
||||
if (y > 199) y = 199;
|
||||
snprintf(buffer, 8, "%d,%d", x, y);
|
||||
SSM(SCI_REPLACETARGET, -1, (sptr_t)buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,6 +447,37 @@ EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
|
|||
}
|
||||
|
||||
|
||||
static int findClosestPoint(VectorDataT *self, int x, int y) {
|
||||
int closest = -1;
|
||||
int distance = INT_MAX;
|
||||
int temp;
|
||||
int i;
|
||||
char buffer[8];
|
||||
|
||||
// Find closest point to mouse pointer.
|
||||
for (i = 0; i < arrlen(self->pointList); i++) {
|
||||
temp = sqrt(pow(x - self->pointList[i]->x, 2) + pow(y - self->pointList[i]->y, 2));
|
||||
if (temp < distance) {
|
||||
closest = i;
|
||||
distance = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Did we find a point to edit?
|
||||
if (closest >= 0) {
|
||||
// Find first occurrence of it in the text editor.
|
||||
snprintf(buffer, 8, "%d,%d", self->pointList[closest]->x, self->pointList[closest]->y);
|
||||
SSM(SCI_TARGETWHOLEDOCUMENT, 0, 0);
|
||||
SSM(SCI_SETSEARCHFLAGS, SCFIND_NONE, 0);
|
||||
temp = SSM(SCI_SEARCHINTARGET, strlen(buffer), (sptr_t)buffer);
|
||||
// Select the text.
|
||||
SSM(SCI_SETSEL, temp, temp + strlen(buffer));
|
||||
return temp;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int getWord(VecByteCodeT *bytecode, int *index) {
|
||||
int word;
|
||||
|
||||
|
@ -1240,42 +1253,28 @@ EVENT void toolCircleClicked(GtkToolButton *object, gpointer userData) {
|
|||
EVENT void toolColorClicked(GtkToolButton *object, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
GtkWidget *dialog;
|
||||
GdkRGBA colors[16];
|
||||
GdkRGBA selected;
|
||||
ColorT colors[16];
|
||||
char temp[4];
|
||||
int i;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
double scale = 1.0/256.0;
|
||||
|
||||
(void)object;
|
||||
|
||||
// Load the current JoeyLib palette into the dialog.
|
||||
for (i=0; i<16; i++) {
|
||||
jlPaletteGet(self->jlc, i, &r, &g, &b);
|
||||
colors[i].alpha = 1.0;
|
||||
colors[i].red = (double)r * scale;
|
||||
colors[i].green = (double)g * scale;
|
||||
colors[i].blue = (double)b * scale;
|
||||
jlPaletteGet(self->jlc, i, &colors[i].red, &colors[i].green, &colors[i].blue);
|
||||
}
|
||||
|
||||
// Build the dialog.
|
||||
dialog = gtk_color_chooser_dialog_new("Color", GTK_WINDOW(self->windowData.window));
|
||||
g_object_set (dialog, "show-editor", FALSE, NULL);
|
||||
gtk_color_chooser_add_palette(GTK_COLOR_CHOOSER(dialog), GTK_ORIENTATION_HORIZONTAL, 4, 16, colors);
|
||||
dialog = color_dialog_new(self->windowData.window, colors);
|
||||
|
||||
// Run the dialog.
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL) {
|
||||
// Figure out which color index they selected.
|
||||
gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(dialog), &selected);
|
||||
for (i=0; i<16; i++) {
|
||||
if (colors[i].red == selected.red && colors[i].green == selected.green && colors[i].blue == selected.blue) {
|
||||
// Write our selected color into the editor.
|
||||
snprintf(temp, 4, " %d", i);
|
||||
insertCommand(self, "COLOR");
|
||||
insertText(self, temp);
|
||||
}
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
|
||||
i = color_dialog_get_selected(dialog);
|
||||
if (i >= 0) {
|
||||
// Write our selected color into the editor.
|
||||
snprintf(temp, 4, " %d", i);
|
||||
insertCommand(self, "color");
|
||||
insertText(self, temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue