From 8fde1a64d48b1456520cc042a6121f29b72b866f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 14 Jun 2019 23:40:59 +0200 Subject: Generic non-intensity parameter handling --- src/nanolight.c | 163 ++++++++++++++++++++++++++++++++++++++------------------ src/nanolight.h | 9 ++-- 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; in_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; in_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; in_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; }; -- cgit v1.2.3