summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2019-06-14 23:40:59 +0200
committerThomas White <taw@physics.org>2019-06-14 23:40:59 +0200
commit8fde1a64d48b1456520cc042a6121f29b72b866f (patch)
tree65105487dc256c93c261c7acf9573a2694a8f274
parente438521b9d9dbae42fb2bfa572e410a7f7dca591 (diff)
Generic non-intensity parameter handling
-rw-r--r--src/nanolight.c163
-rw-r--r--src/nanolight.h9
2 files changed, 116 insertions, 56 deletions
diff --git a/src/nanolight.c b/src/nanolight.c
index 09f8a40..46f6efc 100644
--- a/src/nanolight.c
+++ b/src/nanolight.c
@@ -147,9 +147,22 @@ static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fo
}
+static const char *attr_text(enum attr_class cls)
+{
+ switch ( cls ) {
+ case ATT_INTENSITY : return "Intensity";
+ case ATT_PAN : return "(pan)";
+ case ATT_TILT : return "Pan/tilt";
+ case ATT_STROBE : return "Strobe";
+ default : return "(unknown)";
+ }
+}
+
+
static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct nanolight *nl)
{
int w, h;
+ int ch;
int i;
PangoContext *pc;
PangoFontDescription *fontdesc;
@@ -173,6 +186,7 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct nanolight *nl)
cairo_stroke(cr);
/* Fixtures */
+ cairo_save(cr);
cairo_translate(cr, OVERALL_BORDER, OVERALL_BORDER);
x = FIXTURE_BORDER;
y = FIXTURE_BORDER;
@@ -189,26 +203,36 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct nanolight *nl)
y += nl->fixture_width*3.0/2.0 + FIXTURE_BORDER*2;
}
}
+ cairo_restore(cr);
/* Command line */
pango_layout_set_text(nl->layout, nl->cmdline, -1);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_save(cr);
- cairo_translate(cr, 0.0, h - OVERALL_BORDER*2 - 20.0);
+ cairo_translate(cr, OVERALL_BORDER, h - OVERALL_BORDER - 20.0);
cairo_move_to(cr, 0.0, 0.0);
pango_cairo_show_layout(cr, nl->layout);
pango_layout_get_cursor_pos(nl->layout, nl->cursor_idx, &cursor, NULL);
x = pango_units_to_double(cursor.x);
y = pango_units_to_double(cursor.y);
- h = pango_units_to_double(cursor.height);
+ ch = pango_units_to_double(cursor.height);
cairo_move_to(cr, x, y);
- cairo_line_to(cr, x, y+h);
+ cairo_line_to(cr, x, y+ch);
cairo_set_line_width(cr, 3.0);
cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
cairo_set_source_rgb(cr, 0.8, 0.4, 0.4);
cairo_stroke(cr);
cairo_restore(cr);
+ /* Selected attribute indicator */
+ if ( nl->n_sel > 0 ) {
+ pango_layout_set_text(nl->sa_layout, attr_text(nl->sel_attr), -1);
+ cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
+ pango_layout_set_width(nl->sa_layout, pango_units_from_double(200.0));
+ cairo_move_to(cr, w - 200.0 - OVERALL_BORDER, h-OVERALL_BORDER-20.0);
+ pango_cairo_show_layout(cr, nl->sa_layout);
+ }
+
return FALSE;
}
@@ -314,59 +338,78 @@ static void set_start_attrs(struct nanolight *nl, enum attr_class cls)
}
-static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event, struct nanolight *nl)
+static gboolean button_press_sig(GtkWidget *da, GdkEventButton *event, struct nanolight *nl)
{
- gdouble x, y;
- int i;
- signed int pan_inc, tilt_inc;
+#if 0
+ GdkSeat *seat;
GdkWindow *win = gtk_widget_get_window(nl->da);
- gdk_window_get_device_position_double(win, nl->pointer, &x, &y, NULL);
+ seat = gdk_display_get_default_seat(gdk_display_get_default());
+ nl->pointer = gdk_seat_get_pointer(seat);
+#endif
+
+ set_start_attrs(nl, nl->sel_attr);
- pan_inc = 9*(x - nl->x_orig);
- tilt_inc = 9*(y - nl->y_orig);
- for ( i=0; i<nl->n_sel; i++ ) {
- int n;
- struct fixture *fix = &nl->fixtures[nl->selection[i]];
- if ( find_attribute(fix, ATT_PAN, &n) ) {
- signed int nv = fix->attr_vals_start[n] + pan_inc;
- cap_value(fix, n, &nv);
- fix->attr_vals[n] = nv;
- }
- if ( find_attribute(fix, ATT_TILT, &n) ) {
- signed int nv = fix->attr_vals_start[n] + tilt_inc;
- cap_value(fix, n, &nv);
- fix->attr_vals[n] = nv;
- }
+ /* If altering tilt, also change pan */
+ if ( nl->sel_attr == ATT_TILT ) {
+ set_start_attrs(nl, ATT_PAN);
}
- redraw(nl);
+ nl->x_orig = event->x;
+ nl->y_orig = event->y;
+ nl->dragging = 1;
return FALSE;
}
-static void update_mouse_orientation(struct nanolight *nl)
+static gboolean button_release_sig(GtkWidget *da, GdkEventButton *event, struct nanolight *nl)
{
- if ( (nl->n_sel > 0) && (nl->mouse_orientation == 0) ) {
+ nl->dragging = 0;
+ return FALSE;
+}
- GdkSeat *seat;
- GdkWindow *win = gtk_widget_get_window(nl->da);
- seat = gdk_display_get_default_seat(gdk_display_get_default());
- nl->pointer = gdk_seat_get_pointer(seat);
- gdk_window_get_device_position_double(win, nl->pointer,
- &nl->x_orig, &nl->y_orig, NULL);
- set_start_attrs(nl, ATT_PAN);
- set_start_attrs(nl, ATT_TILT);
+static gboolean motion_sig(GtkWidget *da, GdkEventMotion *event, struct nanolight *nl)
+{
+ int i;
- nl->mouse_orientation = g_signal_connect(G_OBJECT(nl->da), "motion-notify-event",
- G_CALLBACK(motion_sig), nl);
+ if ( !nl->dragging ) return FALSE;
- } else if ( nl->mouse_orientation != 0 ) {
- g_signal_handler_disconnect(nl->da, nl->mouse_orientation);
- nl->mouse_orientation = 0;
+ if ( nl->sel_attr == ATT_TILT ) {
+ double pan_inc, tilt_inc;
+ pan_inc = 9*(event->x - nl->x_orig);
+ tilt_inc = 9*(event->y - nl->y_orig);
+ for ( i=0; i<nl->n_sel; i++ ) {
+ int n;
+ struct fixture *fix = &nl->fixtures[nl->selection[i]];
+ if ( find_attribute(fix, ATT_PAN, &n) ) {
+ signed int nv = fix->attr_vals_start[n] + pan_inc;
+ cap_value(fix, n, &nv);
+ fix->attr_vals[n] = nv;
+ }
+ if ( find_attribute(fix, ATT_TILT, &n) ) {
+ signed int nv = fix->attr_vals_start[n] + tilt_inc;
+ cap_value(fix, n, &nv);
+ fix->attr_vals[n] = nv;
+ }
+ }
+ } else {
+ double inc;
+ inc = event->y - nl->y_orig;
+ for ( i=0; i<nl->n_sel; i++ ) {
+ int n;
+ struct fixture *fix = &nl->fixtures[nl->selection[i]];
+ if ( find_attribute(fix, nl->sel_attr, &n) ) {
+ signed int nv = fix->attr_vals_start[n] + inc;
+ cap_value(fix, n, &nv);
+ fix->attr_vals[n] = nv;
+ }
+ }
}
+
+ redraw(nl);
+ return FALSE;
}
@@ -378,18 +421,18 @@ static void home_value(struct nanolight *nl)
struct fixture *fix = &nl->fixtures[nl->selection[i]];
int n;
- if ( nl->mouse_orientation ) {
- GdkWindow *win = gtk_widget_get_window(nl->da);
+ if ( nl->sel_attr == ATT_TILT ) {
if ( find_attribute(fix, ATT_PAN, &n) ) {
fix->attr_vals[n] = fix->cls->attrs[n].home;
}
if ( find_attribute(fix, ATT_TILT, &n) ) {
fix->attr_vals[n] = fix->cls->attrs[n].home;
}
- gdk_window_get_device_position_double(win, nl->pointer,
- &nl->x_orig, &nl->y_orig, NULL);
- set_start_attrs(nl, ATT_PAN);
- set_start_attrs(nl, ATT_TILT);
+ nl->dragging = 0;
+ } else {
+ if ( find_attribute(fix, nl->sel_attr, &n) ) {
+ fix->attr_vals[n] = fix->cls->attrs[n].home;
+ }
}
}
@@ -421,15 +464,13 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct nanoligh
nl->cmdline[0] = '\0';
nl->cursor_idx = 0;
nl->n_sel = 0;
- update_mouse_orientation(nl);
- redraw(nl);
+ nl->dragging = 0;
claim = 1;
break;
case GDK_KEY_BackSpace :
nl->cursor_idx -= delete_char(nl->cmdline);
claim = 1;
- redraw(nl);
break;
case GDK_KEY_KP_Enter :
@@ -448,7 +489,12 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct nanoligh
break;
case GDK_KEY_F1 :
- update_mouse_orientation(nl);
+ nl->sel_attr = ATT_TILT;
+ claim = 1;
+ break;
+
+ case GDK_KEY_F2 :
+ nl->sel_attr = ATT_STROBE;
claim = 1;
break;
@@ -458,6 +504,8 @@ static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct nanoligh
/* Throw the event to the IM context and let it sort things out */
r = gtk_im_context_filter_keypress(GTK_IM_CONTEXT(nl->im_context), event);
if ( r ) claim = 1;
+ } else {
+ redraw(nl);
}
if ( claim ) return TRUE;
@@ -477,13 +525,21 @@ static gint realise_sig(GtkWidget *da, struct nanolight *nl)
gdk_window_set_accept_focus(win, TRUE);
g_signal_connect(G_OBJECT(nl->im_context), "commit", G_CALLBACK(im_commit_sig), nl);
g_signal_connect(G_OBJECT(da), "key-press-event", G_CALLBACK(key_press_sig), nl);
+ g_signal_connect(G_OBJECT(da), "button-press-event", G_CALLBACK(button_press_sig), nl);
+ g_signal_connect(G_OBJECT(da), "button-release-event", G_CALLBACK(button_release_sig), nl);
+ g_signal_connect(G_OBJECT(da), "motion-notify-event", G_CALLBACK(motion_sig), nl);
pc = gtk_widget_get_pango_context(da);
- nl->layout = pango_layout_new(pc);
fontdesc = pango_font_description_from_string("Comfortaa Bold 16");
+
+ nl->layout = pango_layout_new(pc);
pango_layout_set_alignment(nl->layout, PANGO_ALIGN_LEFT);
pango_layout_set_font_description(nl->layout, fontdesc);
+ nl->sa_layout = pango_layout_new(pc);
+ pango_layout_set_alignment(nl->sa_layout, PANGO_ALIGN_RIGHT);
+ pango_layout_set_font_description(nl->sa_layout, fontdesc);
+
return FALSE;
}
@@ -567,7 +623,8 @@ int main(int argc, char *argv[])
nl.cmdline[0] = '\0';
nl.cursor_idx = 0;
nl.n_sel = 0;
- nl.mouse_orientation = 0;
+ nl.sel_attr = ATT_TILT;
+ nl.dragging = 0;
create_fixture(&nl, &cls, "mh1", 1);
create_fixture(&nl, &cls, "mh2", 52);
@@ -586,7 +643,9 @@ int main(int argc, char *argv[])
nl.da = da;
gtk_container_add(GTK_CONTAINER(mainwindow), GTK_WIDGET(da));
gtk_widget_set_can_focus(GTK_WIDGET(da), TRUE);
- gtk_widget_add_events(da, GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
+ gtk_widget_add_events(da, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK
+ | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
+ | GDK_BUTTON_MOTION_MASK);
g_signal_connect(G_OBJECT(da), "draw", G_CALLBACK(draw_sig), &nl);
g_signal_connect(G_OBJECT(da), "realize", G_CALLBACK(realise_sig), &nl);
diff --git a/src/nanolight.h b/src/nanolight.h
index d3ceb27..1e0a0fd 100644
--- a/src/nanolight.h
+++ b/src/nanolight.h
@@ -79,14 +79,15 @@ struct nanolight
char cmdline[1024];
int cursor_idx;
PangoLayout *layout;
+ PangoLayout *sa_layout;
int selection[1024];
int n_sel;
+ enum attr_class sel_attr;
+ int dragging;
- GdkDevice *pointer;
- gulong mouse_orientation;
- gdouble x_orig;
- gdouble y_orig;
+ double x_orig;
+ double y_orig;
};