Compare commits
3 Commits
392d49a5b7
...
5890a2aaa7
| Author | SHA1 | Date | |
|---|---|---|---|
| 5890a2aaa7 | |||
|
|
ed49bc5f14 | ||
|
|
f593d762fb |
@@ -1,3 +1,6 @@
|
|||||||
|
#include "src/ui/uicontroller.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
#include "./applicationstate.h"
|
#include "./applicationstate.h"
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
#include "gtk/gtk.h"
|
#include "gtk/gtk.h"
|
||||||
@@ -39,10 +42,32 @@ static void appstate_on_color_change(VektorColorWheel* wheel, gpointer user_data
|
|||||||
if(appstate->selectedShape != NULL) {
|
if(appstate->selectedShape != NULL) {
|
||||||
appstate->selectedShape->style.stroke_color = c;
|
appstate->selectedShape->style.stroke_color = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set entry fields under the color selector
|
||||||
|
char *str_r, *str_g, *str_b;
|
||||||
|
str_r = g_strdup_printf("%d", c.r);
|
||||||
|
str_g = g_strdup_printf("%d", c.g);
|
||||||
|
str_b = g_strdup_printf("%d", c.b);
|
||||||
|
gtk_editable_set_text(GTK_EDITABLE(appstate->widgetState->sidepanelEntryR), str_r);
|
||||||
|
gtk_editable_set_text(GTK_EDITABLE(appstate->widgetState->sidepanelEntryG), str_g);
|
||||||
|
gtk_editable_set_text(GTK_EDITABLE(appstate->widgetState->sidepanelEntryB), str_b);
|
||||||
|
|
||||||
gtk_gl_area_queue_render(GTK_GL_AREA(appstate->widgetState->workspaceCanvas));
|
gtk_gl_area_queue_render(GTK_GL_AREA(appstate->widgetState->workspaceCanvas));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void appstate_on_entry_update(GtkEntry* entry, gpointer user_data) {
|
||||||
|
VektorWidgetState* widgetState = (VektorWidgetState*)user_data;
|
||||||
|
unsigned char r = (unsigned char)atoi(gtk_editable_get_text(GTK_EDITABLE(widgetState->sidepanelEntryR)));
|
||||||
|
unsigned char g = (unsigned char)atoi(gtk_editable_get_text(GTK_EDITABLE(widgetState->sidepanelEntryG)));
|
||||||
|
unsigned char b = (unsigned char)atoi(gtk_editable_get_text(GTK_EDITABLE(widgetState->sidepanelEntryB)));
|
||||||
|
|
||||||
|
g_print("%d", r);
|
||||||
|
vektor_color_wheel_set_color(
|
||||||
|
VEKTOR_COLOR_WHEEL(widgetState->workspaceColorPicker),
|
||||||
|
(VektorColor){.r = r, .g = g, .b = b}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static void canvas_onclick(GtkGestureClick* gesture, int n_press, double x,
|
static void canvas_onclick(GtkGestureClick* gesture, int n_press, double x,
|
||||||
double y, gpointer user_data) {
|
double y, gpointer user_data) {
|
||||||
|
|
||||||
@@ -118,7 +143,7 @@ void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) {
|
|||||||
*stateOut->shapeBuffer = (VektorShapeBuffer){0};
|
*stateOut->shapeBuffer = (VektorShapeBuffer){0};
|
||||||
stateOut->canvas = malloc(sizeof(VektorCanvas));
|
stateOut->canvas = malloc(sizeof(VektorCanvas));
|
||||||
stateOut->widgetState = wstate;
|
stateOut->widgetState = wstate;
|
||||||
stateOut->currentColor = vektor_color_blank;
|
stateOut->currentColor = vektor_color_solid(0, 0, 0);
|
||||||
stateOut->selectedShape = NULL;
|
stateOut->selectedShape = NULL;
|
||||||
vektor_canvas_init(wstate, stateOut->canvas, stateOut->shapeBuffer);
|
vektor_canvas_init(wstate, stateOut->canvas, stateOut->shapeBuffer);
|
||||||
|
|
||||||
@@ -139,6 +164,15 @@ void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) {
|
|||||||
g_signal_connect(G_OBJECT(wstate->workspaceColorPicker), "color-changed",
|
g_signal_connect(G_OBJECT(wstate->workspaceColorPicker), "color-changed",
|
||||||
G_CALLBACK(appstate_on_color_change), stateOut);
|
G_CALLBACK(appstate_on_color_change), stateOut);
|
||||||
|
|
||||||
|
// hook rgb entries change
|
||||||
|
g_signal_connect(G_OBJECT(wstate->sidepanelEntryR), "activate",
|
||||||
|
G_CALLBACK(appstate_on_entry_update), stateOut->widgetState);
|
||||||
|
g_signal_connect(G_OBJECT(wstate->sidepanelEntryG), "activate",
|
||||||
|
G_CALLBACK(appstate_on_entry_update), stateOut->widgetState);
|
||||||
|
g_signal_connect(G_OBJECT(wstate->sidepanelEntryB), "activate",
|
||||||
|
G_CALLBACK(appstate_on_entry_update), stateOut->widgetState);
|
||||||
|
|
||||||
|
|
||||||
// Add click gesture to canvas
|
// Add click gesture to canvas
|
||||||
GtkGesture* canvasClickGesture = gtk_gesture_click_new();
|
GtkGesture* canvasClickGesture = gtk_gesture_click_new();
|
||||||
g_signal_connect(G_OBJECT(canvasClickGesture), "pressed",
|
g_signal_connect(G_OBJECT(canvasClickGesture), "pressed",
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) {
|
|||||||
GTK_WINDOW(gtk_builder_get_object(builder, "main_window"));
|
GTK_WINDOW(gtk_builder_get_object(builder, "main_window"));
|
||||||
stateOut->workspacePaned =
|
stateOut->workspacePaned =
|
||||||
GTK_PANED(gtk_builder_get_object(builder, "workspace_paned"));
|
GTK_PANED(gtk_builder_get_object(builder, "workspace_paned"));
|
||||||
|
stateOut->sidepanelPaned =
|
||||||
|
GTK_PANED(gtk_builder_get_object(builder, "sidepanel"));
|
||||||
stateOut->workspaceCanvas =
|
stateOut->workspaceCanvas =
|
||||||
GTK_GL_AREA(gtk_builder_get_object(builder, "workspace"));
|
GTK_GL_AREA(gtk_builder_get_object(builder, "workspace"));
|
||||||
|
|
||||||
@@ -57,6 +59,13 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) {
|
|||||||
stateOut->workspaceColorPicker =
|
stateOut->workspaceColorPicker =
|
||||||
VEKTOR_COLOR_WHEEL(gtk_builder_get_object(builder, "color_picker"));
|
VEKTOR_COLOR_WHEEL(gtk_builder_get_object(builder, "color_picker"));
|
||||||
|
|
||||||
|
stateOut->sidepanelEntryR =
|
||||||
|
GTK_ENTRY(gtk_builder_get_object(builder, "spin_color_r"));
|
||||||
|
stateOut->sidepanelEntryG =
|
||||||
|
GTK_ENTRY(gtk_builder_get_object(builder, "spin_color_g"));
|
||||||
|
stateOut->sidepanelEntryB =
|
||||||
|
GTK_ENTRY(gtk_builder_get_object(builder, "spin_color_b"));
|
||||||
|
|
||||||
// Set window properties
|
// Set window properties
|
||||||
gtk_window_set_application(stateOut->window, app);
|
gtk_window_set_application(stateOut->window, app);
|
||||||
gtk_window_set_title(stateOut->window, "Vektor");
|
gtk_window_set_title(stateOut->window, "Vektor");
|
||||||
@@ -67,4 +76,5 @@ void vektor_uictrl_init(GtkApplication* app, VektorWidgetState* stateOut) {
|
|||||||
|
|
||||||
void vektor_uictrl_map(VektorWidgetState* state) {
|
void vektor_uictrl_map(VektorWidgetState* state) {
|
||||||
gtk_paned_set_position(state->workspacePaned, 800 * .7);
|
gtk_paned_set_position(state->workspacePaned, 800 * .7);
|
||||||
|
gtk_paned_set_position(state->sidepanelPaned, 250);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ all the widgets used in internal logic of the program
|
|||||||
typedef struct VektorWidgetState {
|
typedef struct VektorWidgetState {
|
||||||
GtkWindow* window;
|
GtkWindow* window;
|
||||||
GtkPaned* workspacePaned;
|
GtkPaned* workspacePaned;
|
||||||
|
GtkPaned* sidepanelPaned;
|
||||||
GtkGLArea* workspaceCanvas;
|
GtkGLArea* workspaceCanvas;
|
||||||
|
|
||||||
GtkButton* workspaceButtonMasterShapes;
|
GtkButton* workspaceButtonMasterShapes;
|
||||||
@@ -22,6 +23,10 @@ typedef struct VektorWidgetState {
|
|||||||
|
|
||||||
VektorColorWheel* workspaceColorPicker;
|
VektorColorWheel* workspaceColorPicker;
|
||||||
|
|
||||||
|
GtkEntry* sidepanelEntryR;
|
||||||
|
GtkEntry* sidepanelEntryG;
|
||||||
|
GtkEntry* sidepanelEntryB;
|
||||||
|
|
||||||
// GtkWidget* Workspace
|
// GtkWidget* Workspace
|
||||||
} VektorWidgetState;
|
} VektorWidgetState;
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,51 @@ static gboolean point_in_triangle(
|
|||||||
return (*u >= 0 && *v >= 0 && *w >= 0);
|
return (*u >= 0 && *v >= 0 && *w >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void closest_point_on_segment(
|
||||||
|
double px, double py,
|
||||||
|
double ax, double ay,
|
||||||
|
double bx, double by,
|
||||||
|
double *rx, double *ry)
|
||||||
|
{
|
||||||
|
double abx = bx - ax;
|
||||||
|
double aby = by - ay;
|
||||||
|
|
||||||
|
double apx = px - ax;
|
||||||
|
double apy = py - ay;
|
||||||
|
|
||||||
|
double t = (apx*abx + apy*aby) / (abx*abx + aby*aby);
|
||||||
|
|
||||||
|
if (t < 0) t = 0;
|
||||||
|
if (t > 1) t = 1;
|
||||||
|
|
||||||
|
*rx = ax + abx * t;
|
||||||
|
*ry = ay + aby * t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void closest_point_on_triangle(
|
||||||
|
double px, double py,
|
||||||
|
double ax, double ay,
|
||||||
|
double bx, double by,
|
||||||
|
double cx, double cy,
|
||||||
|
double *rx, double *ry)
|
||||||
|
{
|
||||||
|
double p1x,p1y;
|
||||||
|
double p2x,p2y;
|
||||||
|
double p3x,p3y;
|
||||||
|
|
||||||
|
closest_point_on_segment(px,py, ax,ay, bx,by, &p1x,&p1y);
|
||||||
|
closest_point_on_segment(px,py, bx,by, cx,cy, &p2x,&p2y);
|
||||||
|
closest_point_on_segment(px,py, cx,cy, ax,ay, &p3x,&p3y);
|
||||||
|
|
||||||
|
double d1 = (px-p1x)*(px-p1x) + (py-p1y)*(py-p1y);
|
||||||
|
double d2 = (px-p2x)*(px-p2x) + (py-p2y)*(py-p2y);
|
||||||
|
double d3 = (px-p3x)*(px-p3x) + (py-p3y)*(py-p3y);
|
||||||
|
|
||||||
|
if (d1 <= d2 && d1 <= d3) { *rx = p1x; *ry = p1y; }
|
||||||
|
else if (d2 <= d3) { *rx = p2x; *ry = p2y; }
|
||||||
|
else { *rx = p3x; *ry = p3y; }
|
||||||
|
}
|
||||||
|
|
||||||
static void vektor_color_wheel_snapshot(GtkWidget* widget, GtkSnapshot* snapshot) {
|
static void vektor_color_wheel_snapshot(GtkWidget* widget, GtkSnapshot* snapshot) {
|
||||||
VektorColorWheel* self = VEKTOR_COLOR_WHEEL(widget);
|
VektorColorWheel* self = VEKTOR_COLOR_WHEEL(widget);
|
||||||
|
|
||||||
@@ -147,7 +192,7 @@ static void vektor_color_wheel_snapshot(GtkWidget* widget, GtkSnapshot* snapshot
|
|||||||
cairo_arc(cr, px, py, 5, 0, 2*M_PI);
|
cairo_arc(cr, px, py, 5, 0, 2*M_PI);
|
||||||
|
|
||||||
float fr, fg, fb;
|
float fr, fg, fb;
|
||||||
vektor_colorout_wheel_get_color(self, &fr, &fg, &fb);
|
vektor_color_wheel_get_colorout(self, &fr, &fg, &fb);
|
||||||
cairo_set_source_rgb(cr, fr, fg, fb);
|
cairo_set_source_rgb(cr, fr, fg, fb);
|
||||||
cairo_fill_preserve(cr);
|
cairo_fill_preserve(cr);
|
||||||
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
|
cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
|
||||||
@@ -206,7 +251,8 @@ static void on_click(GtkGestureClick* gesture, int n_press, double x, double y,
|
|||||||
double cy2 = cy - 0.866 * triangle_radius;
|
double cy2 = cy - 0.866 * triangle_radius;
|
||||||
|
|
||||||
double u,v,w;
|
double u,v,w;
|
||||||
if(point_in_triangle(x,y, ax,ay, bx,by, cx2,cy2, &u,&v,&w)) {
|
gboolean inside = point_in_triangle(x,y, ax,ay, bx,by, cx2,cy2, &u,&v,&w);
|
||||||
|
if(inside) { // pick point in the triangle
|
||||||
|
|
||||||
double denom = u + v;
|
double denom = u + v;
|
||||||
if (denom > 0.0001) { // avoid div-by-zero at black vertex
|
if (denom > 0.0001) { // avoid div-by-zero at black vertex
|
||||||
@@ -222,14 +268,41 @@ static void on_click(GtkGestureClick* gesture, int n_press, double x, double y,
|
|||||||
double dy = y - cy;
|
double dy = y - cy;
|
||||||
double dist = sqrt(dx*dx+dy*dy);
|
double dist = sqrt(dx*dx+dy*dy);
|
||||||
|
|
||||||
if(dist > inner_radius && dist < outer_radius) {
|
if(dist > inner_radius && dist < outer_radius) { // pick point on color wheel
|
||||||
|
|
||||||
double angle = atan2(dy, dx);
|
double angle = atan2(dy, dx);
|
||||||
if(angle < 0) { angle += 2 * M_PI; }
|
if(angle < 0) { angle += 2 * M_PI; }
|
||||||
|
|
||||||
wheel->hue = angle / (2*M_PI);
|
wheel->hue = angle / (2*M_PI);
|
||||||
g_signal_emit(wheel, signals[COLOR_CHANGED], 0);
|
g_signal_emit(wheel, signals[COLOR_CHANGED], 0);
|
||||||
|
|
||||||
|
} else if (dist < inner_radius) { // snap to triangle edge
|
||||||
|
double sx,sy;
|
||||||
|
|
||||||
|
closest_point_on_triangle(
|
||||||
|
x,y,
|
||||||
|
ax,ay,
|
||||||
|
bx,by,
|
||||||
|
cx2,cy2,
|
||||||
|
&sx,&sy
|
||||||
|
);
|
||||||
|
|
||||||
|
x = sx;
|
||||||
|
y = sy;
|
||||||
|
|
||||||
|
point_in_triangle(x,y, ax,ay, bx,by, cx2,cy2, &u,&v,&w);
|
||||||
|
|
||||||
|
// calculate triangle point
|
||||||
|
double denom = u + v;
|
||||||
|
if (denom > 0.0001) {
|
||||||
|
wheel->saturation = u / denom;
|
||||||
|
} else {
|
||||||
|
wheel->saturation = 0.0;
|
||||||
|
}
|
||||||
|
wheel->lightness = denom;
|
||||||
|
g_signal_emit(wheel, signals[COLOR_CHANGED], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_widget_queue_draw(widget);
|
gtk_widget_queue_draw(widget);
|
||||||
@@ -289,13 +362,25 @@ VektorColor vektor_color_wheel_get_color(VektorColorWheel* wheel) {
|
|||||||
return (VektorColor) {
|
return (VektorColor) {
|
||||||
.r = (unsigned char)(r*255),
|
.r = (unsigned char)(r*255),
|
||||||
.g = (unsigned char)(g*255),
|
.g = (unsigned char)(g*255),
|
||||||
.b = (unsigned char)(b*255)
|
.b = (unsigned char)(b*255) ,
|
||||||
|
.a = 255
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void vektor_colorout_wheel_get_color(VektorColorWheel* wheel, float* r, float* g, float* b) {
|
void vektor_color_wheel_get_colorout(VektorColorWheel* wheel, float* r, float* g, float* b) {
|
||||||
gtk_hsv_to_rgb(wheel->hue,
|
gtk_hsv_to_rgb(wheel->hue,
|
||||||
wheel->saturation,
|
wheel->saturation,
|
||||||
wheel->lightness,
|
wheel->lightness,
|
||||||
r, g, b);
|
r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vektor_color_wheel_set_color(VektorColorWheel* wheel, VektorColor c) {
|
||||||
|
float h,s,v;
|
||||||
|
gtk_rgb_to_hsv(c.r/255.0, c.g/255.0, c.b/255.0, &h, &s, &v);
|
||||||
|
wheel->hue = (float)h;
|
||||||
|
wheel->saturation = (float)s;
|
||||||
|
wheel->lightness = (float)v;
|
||||||
|
|
||||||
|
gtk_widget_queue_draw(GTK_WIDGET(wheel));
|
||||||
|
g_signal_emit(wheel, signals[COLOR_CHANGED], 0);
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ G_DECLARE_FINAL_TYPE(VektorColorWheel, vektor_color_wheel, VEKTOR, COLOR_WHEEL,
|
|||||||
|
|
||||||
GtkWidget* vektor_color_wheel_new(void);
|
GtkWidget* vektor_color_wheel_new(void);
|
||||||
VektorColor vektor_color_wheel_get_color(VektorColorWheel* wheel);
|
VektorColor vektor_color_wheel_get_color(VektorColorWheel* wheel);
|
||||||
void vektor_colorout_wheel_get_color(VektorColorWheel* wheel, float* r, float* g, float* b);
|
void vektor_color_wheel_get_colorout(VektorColorWheel* wheel, float* r, float* g, float* b);
|
||||||
|
void vektor_color_wheel_set_color(VektorColorWheel* wheel, VektorColor c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
64
ui/main.ui
64
ui/main.ui
@@ -148,10 +148,68 @@
|
|||||||
<property name="margin-bottom">6</property>
|
<property name="margin-bottom">6</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<object class="VektorColorWheel" id="color_picker">
|
<object class="GtkBox">
|
||||||
<property name="hexpand">true</property>
|
<property name="orientation">vertical</property>
|
||||||
<property name="vexpand">true</property>
|
|
||||||
|
<child>
|
||||||
|
<object class="VektorColorWheel" id="color_picker">
|
||||||
|
<property name="hexpand">true</property>
|
||||||
|
<property name="vexpand">true</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="orientation">horizontal</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">R</property>
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">6</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="spin_color_r">
|
||||||
|
<property name="text">0</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">G</property>
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">6</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="spin_color_g">
|
||||||
|
<property name="text">0</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label">B</property>
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">6</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="spin_color_b">
|
||||||
|
<property name="text">0</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
|
||||||
</object>
|
</object>
|
||||||
|
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
</object>
|
</object>
|
||||||
|
|||||||
Reference in New Issue
Block a user