summaryrefslogtreecommitdiff
path: root/src/nanolight.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nanolight.c')
-rw-r--r--src/nanolight.c207
1 files changed, 195 insertions, 12 deletions
diff --git a/src/nanolight.c b/src/nanolight.c
index 4c657df..6cb06e6 100644
--- a/src/nanolight.c
+++ b/src/nanolight.c
@@ -33,6 +33,7 @@
#define _(x) gettext(x)
#include "nanolight.h"
+#include "command.h"
static void show_help(const char *s)
{
@@ -43,12 +44,28 @@ static void show_help(const char *s)
#define OVERALL_BORDER (20.0)
#define OVERALL_SPLIT (0.5)
+#define FIXTURE_BORDER (5.0)
+
+static double get_attr_val(struct fixture *fix, enum attr_class acls)
+{
+ int i;
+ for ( i=0; i<fix->cls->n_attrs; i++ ) {
+ if ( fix->cls->attrs[i].cls == acls ) {
+ int max = 255;
+ if ( fix->cls->attrs[i].props & ATTR_16BIT ) max = 65535;
+ return (double)fix->attr_vals[i] / max;
+ }
+ }
+ return 0.0;
+}
+
static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fontdesc,
- struct nanolight *nl, struct fixture *fx)
+ struct nanolight *nl, struct fixture *fix)
{
PangoLayout *layout;
- const double w = nl->fixture_width;
+ const double w = 40.0;
+ char tmp[32];
cairo_rectangle(cr, 0.5, 0.5, w, 3.0/2.0*w);
cairo_set_source_rgb(cr, 0.3, 0.3, 0.3);
@@ -57,13 +74,28 @@ static void draw_fixture(cairo_t *cr, PangoContext *pc, PangoFontDescription *fo
cairo_set_line_width(cr, 1.0);
cairo_stroke(cr);
+ /* Label */
layout = pango_layout_new(pc);
- pango_layout_set_text(layout, fx->label, -1);
- pango_layout_set_width(layout, w*PANGO_SCALE);
+ pango_layout_set_text(layout, fix->label, -1);
+ pango_layout_set_width(layout, (w*PANGO_SCALE)-4.0);
pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
pango_layout_set_font_description(layout, fontdesc);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ cairo_move_to(cr, 0.0, 2.0);
pango_cairo_show_layout(cr, layout);
+ g_object_unref(layout);
+
+ /* Intensity */
+ snprintf(tmp, 32, "%.0f %%", get_attr_val(fix, ATT_INTENSITY)*100.0);
+ layout = pango_layout_new(pc);
+ pango_layout_set_text(layout, tmp, -1);
+ pango_layout_set_width(layout, (w*PANGO_SCALE)-4.0);
+ pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
+ pango_layout_set_font_description(layout, fontdesc);
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ cairo_move_to(cr, 0.0, 15.0);
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(layout);
}
@@ -73,11 +105,12 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct nanolight *nl)
int i;
PangoContext *pc;
PangoFontDescription *fontdesc;
+ PangoLayout *layout;
+ double x, y;
w = gtk_widget_get_allocated_width(widget);
h = gtk_widget_get_allocated_height(widget);
pc = gtk_widget_get_pango_context(widget);
- fontdesc = pango_font_description_from_string("Comfortaa Bold 14");
/* Overall background */
cairo_set_source_rgb(cr, 0.0, 0.0, 0.2);
@@ -93,11 +126,153 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct nanolight *nl)
/* Fixtures */
cairo_translate(cr, OVERALL_BORDER, OVERALL_BORDER);
+ x = FIXTURE_BORDER;
+ y = FIXTURE_BORDER;
+ fontdesc = pango_font_description_from_string("Comfortaa Bold 8");
for ( i=0; i<nl->n_fixtures; i++ ) {
+ cairo_save(cr);
+ cairo_translate(cr, x, y);
+ cairo_scale(cr, nl->fixture_width/40.0, nl->fixture_width/40.0);
draw_fixture(cr, pc, fontdesc, nl, &nl->fixtures[i]);
+ cairo_restore(cr);
+ x += nl->fixture_width + FIXTURE_BORDER*2;
+ if ( x + nl->fixture_width + FIXTURE_BORDER*2 > w*OVERALL_SPLIT ) {
+ x = FIXTURE_BORDER;
+ y += nl->fixture_width*3.0/2.0 + FIXTURE_BORDER*2;
+ }
}
/* Command line */
+ layout = pango_layout_new(pc);
+ fontdesc = pango_font_description_from_string("Comfortaa Bold 16");
+ pango_layout_set_text(layout, nl->cmdline, -1);
+ pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
+ pango_layout_set_font_description(layout, fontdesc);
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ cairo_move_to(cr, 0.0, h - OVERALL_BORDER*2 - 20.0);
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(layout);
+
+ return FALSE;
+}
+
+
+static struct fixture *create_fixture(struct nanolight *nl, struct fixture_class *cls,
+ const char *label, int base_addr)
+{
+ struct fixture *fix;
+
+ if ( nl->n_fixtures == nl->max_fixtures ) {
+ struct fixture *fixtures_new;
+ fixtures_new = realloc(nl->fixtures, (64+nl->max_fixtures)*sizeof(struct fixture));
+ if ( fixtures_new == NULL ) return NULL;
+ nl->fixtures = fixtures_new;
+ nl->max_fixtures += 64;
+ }
+
+ fix = &nl->fixtures[nl->n_fixtures++];
+ fix->label = strdup(label);
+ fix->base_addr = base_addr;
+ fix->cls = cls;
+ fix->attr_vals = calloc(cls->n_attrs, sizeof(int));
+ if ( fix->attr_vals == NULL ) {
+ nl->n_fixtures--;
+ return NULL;
+ }
+ return fix;
+}
+
+
+static void redraw(struct nanolight *nl)
+{
+ gint w, h;
+ w = gtk_widget_get_allocated_width(GTK_WIDGET(nl->da));
+ h = gtk_widget_get_allocated_height(GTK_WIDGET(nl->da));
+ gtk_widget_queue_draw_area(GTK_WIDGET(nl->da), 0, 0, w, h);
+}
+
+
+static void execute_command(struct nanolight *nl)
+{
+ if ( command_run(nl->cmdline, nl) == 0 ) {
+ nl->cmdline[0] = '\0';
+ }
+ redraw(nl);
+}
+
+
+static gboolean im_commit_sig(GtkIMContext *im, gchar *str, struct nanolight *nl)
+{
+ size_t cmd_len = strlen(nl->cmdline);
+ if ( cmd_len+strlen(str) > 1023 ) return FALSE;
+ strcat(nl->cmdline, str);
+ redraw(nl);
+ return FALSE;
+}
+
+
+static void delete_char(char *str)
+{
+ char *last;
+ if ( str[0] == '\0' ) return;
+ last = g_utf8_find_prev_char(str, str+strlen(str));
+ last[0] = '\0';
+}
+
+
+static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct nanolight *nl)
+{
+ gboolean r;
+ int claim = 0;
+
+ /* 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 ) return FALSE; /* IM ate it */
+
+ switch ( event->keyval ) {
+
+ case GDK_KEY_Left :
+ claim = 1;
+ break;
+
+ case GDK_KEY_Right :
+ claim = 1;
+ break;
+
+ case GDK_KEY_Return :
+ execute_command(nl);
+ claim = 1;
+ break;
+
+ case GDK_KEY_Escape :
+ nl->cmdline[0] = '\0';
+ redraw(nl);
+ claim = 1;
+ break;
+
+ case GDK_KEY_BackSpace :
+ delete_char(nl->cmdline);
+ claim = 1;
+ redraw(nl);
+ break;
+
+ }
+
+ if ( claim ) return TRUE;
+ return FALSE;
+}
+
+
+static gint realise_sig(GtkWidget *da, struct nanolight *nl)
+{
+ GdkWindow *win = gtk_widget_get_window(da);
+
+ /* Keyboard and input method stuff */
+ nl->im_context = gtk_im_multicontext_new();
+ gtk_im_context_set_client_window(GTK_IM_CONTEXT(nl->im_context), win);
+ 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);
return FALSE;
}
@@ -106,7 +281,6 @@ static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct nanolight *nl)
int main(int argc, char *argv[])
{
struct nanolight nl;
- struct fixture fix;
struct fixture_class cls;
struct attribute attrs[3];
int c;
@@ -163,21 +337,30 @@ int main(int argc, char *argv[])
cls.attrs[2].props = ATTR_16BIT;
cls.attrs[2].addr_offset = 2;
- nl.n_fixtures = 1;
- nl.fixtures = &fix;
- fix.label = "mh1";
- fix.cls = &cls;
-
nl.fixture_width = 80.0;
+ nl.fixtures = NULL;
+ nl.n_fixtures = 0;
+ nl.max_fixtures = 0;
+ nl.cmdline[0] = '\0';
+
+ create_fixture(&nl, &cls, "mh1", 1);
+ create_fixture(&nl, &cls, "mh2", 52);
+ create_fixture(&nl, &cls, "mh3", 103);
+ create_fixture(&nl, &cls, "mh4", 154)->attr_vals[0]=255;
mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_fullscreen(GTK_WINDOW(mainwindow));
+ //gtk_window_fullscreen(GTK_WINDOW(mainwindow));
g_signal_connect_swapped(G_OBJECT(mainwindow), "destroy", gtk_main_quit, NULL);
da = gtk_drawing_area_new();
+ 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);
g_signal_connect(G_OBJECT(da), "draw", G_CALLBACK(draw_sig), &nl);
+ g_signal_connect(G_OBJECT(da), "realize", G_CALLBACK(realise_sig), &nl);
+ gtk_widget_grab_focus(GTK_WIDGET(da));
gtk_widget_show_all(mainwindow);
gtk_main();