diff options
author | Thomas White <taw@physics.org> | 2021-06-09 17:58:24 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2021-06-19 19:49:05 +0200 |
commit | c6c277b79711a0999d6db39a06cc3981cf3fd8a9 (patch) | |
tree | f55592b4513b1a701530d8ac4043ee6fb964cef9 | |
parent | 49b569408adb6c2709adbd816d2a6d0e283320f2 (diff) |
Skeleton fixture display tool
-rw-r--r-- | meson.build | 27 | ||||
-rw-r--r-- | src/starlet-fixture-display.c | 307 |
2 files changed, 334 insertions, 0 deletions
diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..f9ca007 --- /dev/null +++ b/meson.build @@ -0,0 +1,27 @@ +# Meson file for Starlet +project('starlet', 'c', + version : '0.1.0', + license : 'GPL3+', + default_options : ['buildtype=debugoptimized']) + +# Localisation +subdir('po') +add_project_arguments('-DLOCALEDIR="'+join_paths(get_option('prefix'), get_option('localedir'))+'"', + language : 'c') + + +# Dependencies +gnome = import('gnome') +cc = meson.get_compiler('c') +mdep = cc.find_library('m', required : false) +gtk_dep = dependency('gtk+-3.0', required : true) +cairo_dep = dependency('cairo', required : true) +pango_dep = dependency('pango', required : true) +pangocairo_dep = dependency('pangocairo', required : true) + + +# Fixture display tool +executable('starlet-fixture-display', + ['src/starlet-fixture-display.c'], + dependencies : [gtk_dep], + install : true) diff --git a/src/starlet-fixture-display.c b/src/starlet-fixture-display.c new file mode 100644 index 0000000..2f8c29b --- /dev/null +++ b/src/starlet-fixture-display.c @@ -0,0 +1,307 @@ +/* + * starlet-fixture-display.c + * + * Copyright © 2019-2021 Thomas White <taw@bitwiz.me.uk> + * + * This file is part of Starlet. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include <gtk/gtk.h> +#include <getopt.h> +#include <string.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <glib.h> +#include <glib/gstdio.h> + +#include <libintl.h> +#define _(x) gettext(x) + + +#define OVERALL_BORDER (20.0) +#define FIXTURE_BORDER (5.0) + + +struct fixture +{ + char *label; +}; + + +struct fixture_display +{ + double fixture_tile_width; + struct fixture *fixtures; + int n_fixtures; + GtkWidget *da; +}; + + +static void draw_fixture(cairo_t *cr, + PangoContext *pc, + PangoFontDescription *fontdesc, + struct fixture_display *fixd, + struct fixture *fix) +{ + PangoLayout *layout; + const double w = 40.0; + const double h = 3.0/2.0*w; + //char tmp[32]; + + /* Pan/tilt (underneath rectangle) */ +// if ( fix->cls->attributes & PANTILT ) { +// +// double x = w*(1.0 + fix->v.pan)/2.0; +// double y = h*(1.0 - fix->v.tilt)/2.0; +// +// cairo_move_to(cr, x, -1.0); +// cairo_line_to(cr, x, h+1.0); +// cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); +// cairo_set_line_width(cr, 1.0); +// cairo_stroke(cr); +// +// cairo_move_to(cr, -1.0, y); +// cairo_line_to(cr, w+1.0, y); +// cairo_set_source_rgb(cr, 1.0, 0.0, 0.0); +// cairo_set_line_width(cr, 1.0); +// cairo_stroke(cr); +// +// } + + cairo_rectangle(cr, 0.0, 0.0, w, h); + //if ( fixture_selected(fixd, fix) ) { + // cairo_set_source_rgba(cr, 0.3, 0.3, 0.9, 0.9); + //} else { + cairo_set_source_rgba(cr, 0.3, 0.3, 0.3, 0.9); + //} + cairo_fill_preserve(cr); + cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); + cairo_set_line_width(cr, 1.0); + cairo_stroke(cr); + + /* Label */ + layout = pango_layout_new(pc); + 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 %%", fix->v.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); +} + + +static gboolean draw_sig(GtkWidget *widget, cairo_t *cr, struct fixture_display *fixd) +{ + int w, h; + int i; + PangoContext *pc; + PangoFontDescription *fontdesc; + double x, y; + + w = gtk_widget_get_allocated_width(widget); + h = gtk_widget_get_allocated_height(widget); + pc = gtk_widget_get_pango_context(widget); + + /* Overall background */ + cairo_set_source_rgb(cr, 0.0, 0.0, 0.2); + cairo_paint(cr); + + cairo_save(cr); + cairo_translate(cr, OVERALL_BORDER, OVERALL_BORDER); + w -= OVERALL_BORDER*2.0; + h -= OVERALL_BORDER*2.0; + + /* Fixtures */ + x = FIXTURE_BORDER; + y = FIXTURE_BORDER; + fontdesc = pango_font_description_from_string("Comfortaa Bold 8"); + for ( i=0; i<fixd->n_fixtures; i++ ) { + cairo_save(cr); + cairo_translate(cr, x, y); + cairo_scale(cr, fixd->fixture_tile_width/40.0, fixd->fixture_tile_width/40.0); + draw_fixture(cr, pc, fontdesc, fixd, &fixd->fixtures[i]); + cairo_restore(cr); + x += fixd->fixture_tile_width + FIXTURE_BORDER*2; + if ( x + fixd->fixture_tile_width + FIXTURE_BORDER*2 > w ) { + x = FIXTURE_BORDER; + y += fixd->fixture_tile_width*3.0/2.0 + FIXTURE_BORDER*2; + } + } + + cairo_restore(cr); + + return FALSE; +} + + +static void redraw(struct fixture_display *fixd) +{ + gint w, h; + w = gtk_widget_get_allocated_width(GTK_WIDGET(fixd->da)); + h = gtk_widget_get_allocated_height(GTK_WIDGET(fixd->da)); + gtk_widget_queue_draw_area(GTK_WIDGET(fixd->da), 0, 0, w, h); +} + + +static gboolean key_press_sig(GtkWidget *da, GdkEventKey *event, struct fixture_display *fixd) +{ + int claim = 1; + + switch ( event->keyval ) { + + case GDK_KEY_Escape : + /* FIXME: Send (sel #f) */ + break; + + default : + claim = 0; + break; + + } + + if ( claim ) return TRUE; + return FALSE; +} + + +static gint realise_sig(GtkWidget *da, struct fixture_display *fixd) +{ + GdkWindow *win = gtk_widget_get_window(da); + + /* Keyboard and input method stuff */ + gdk_window_set_accept_focus(win, TRUE); + g_signal_connect(G_OBJECT(da), "key-press-event", G_CALLBACK(key_press_sig), fixd); + + return FALSE; +} + + +static gboolean redraw_cb(gpointer data) +{ + redraw((struct fixture_display *)data); + return G_SOURCE_CONTINUE; +} + + +static void get_fixture_list(struct fixture_display *fixd) +{ + int i; + /* FIXME: Dummy */ + int i; + fixd->fixtures = malloc(32*sizeof(struct fixture)); + fixd->n_fixtures = 32; + for ( i=0; i<32; i++ ) { + char tmp[32]; + snprintf(tmp, 31, "mh%i", 1+i); + fixd->fixtures[i].label = strdup(tmp); + } +} + + +static void show_help(const char *s) +{ + printf(_("Syntax: %s [options]\n\n"), s); + printf(_("Show fixtures in Starlet" + " -h, --help Display this help message.\n")); +} + + +int main(int argc, char *argv[]) +{ + struct fixture_display fixd; + int c; + GtkWidget *mainwindow; + GtkWidget *da; + + gtk_init(&argc, &argv); + + const struct option longopts[] = { + {"help", 0, NULL, 'h'}, + {0, 0, NULL, 0} + }; + + while ((c = getopt_long(argc, argv, "h", longopts, NULL)) != -1) { + + switch (c) + { + case 'h' : + show_help(argv[0]); + return 0; + + case 0 : + break; + + default : + return 1; + } + + } + + #if !GLIB_CHECK_VERSION(2,36,0) + g_type_init(); + #endif + + bindtextdomain("starlet", LOCALEDIR); + textdomain("starlet"); + + /* Create main window */ + mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size(GTK_WINDOW(mainwindow), 1024, 768); + g_signal_connect_swapped(G_OBJECT(mainwindow), "destroy", + gtk_main_quit, NULL); + + da = gtk_drawing_area_new(); + + fixd.fixture_tile_width = 60.0; + fixd.fixtures = NULL; + fixd.n_fixtures = 0; + fixd.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_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), &fixd); + g_signal_connect(G_OBJECT(da), "realize", G_CALLBACK(realise_sig), &fixd); + + gtk_widget_grab_focus(GTK_WIDGET(da)); + gtk_widget_show_all(mainwindow); + + g_timeout_add(50, redraw_cb, &fixd); + + get_fixture_list(&fixd); + + gtk_main(); + + return 0; +} |