+ Organ: implement quadratic amplitude envelope, GUI cleanup
[calf.git] / src / ctl_led.cpp
blob2577333d62552ba48b2c967b0796678fd63a900a
1 /* Calf DSP Library
2 * Light emitting diode-like control.
4 * Copyright (C) 2008 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 #include <calf/ctl_led.h>
22 #include <math.h>
23 #include <stdint.h>
24 #include <malloc.h>
26 GtkWidget *
27 calf_led_new()
29 GtkWidget *widget = GTK_WIDGET( g_object_new (CALF_TYPE_LED, NULL ));
30 return widget;
33 static gboolean
34 calf_led_expose (GtkWidget *widget, GdkEventExpose *event)
36 g_assert(CALF_IS_LED(widget));
38 CalfLed *self = CALF_LED(widget);
39 GdkWindow *window = widget->window;
40 cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(window));
42 gdk_cairo_set_source_color(c, &widget->style->bg[0]);
43 cairo_rectangle(c, 0, 0, widget->allocation.width, widget->allocation.height);
44 cairo_fill(c);
46 int xc = widget->allocation.width / 2;
47 int yc = widget->allocation.height / 2;
49 int diameter = (widget->allocation.width < widget->allocation.height ? widget->allocation.width : widget->allocation.height) - 1;
51 cairo_pattern_t *pt = cairo_pattern_create_radial(xc, yc + diameter / 4, 0, xc, yc, diameter / 2);
52 cairo_pattern_add_color_stop_rgb(pt, 0.0, self->led_state ? 1.0 : 0.25, self->led_state ? 0.5 : 0.125, 0.0);
53 cairo_pattern_add_color_stop_rgb(pt, 0.5, self->led_state ? 0.75 : 0.2, 0.0, 0.0);
54 cairo_pattern_add_color_stop_rgb(pt, 1.0, self->led_state ? 0.25 : 0.1, 0.0, 0.0);
56 cairo_arc(c, xc, yc, diameter / 2, 0, 2 * M_PI);
57 cairo_set_line_join(c, CAIRO_LINE_JOIN_BEVEL);
58 cairo_set_source (c, pt);
59 cairo_fill(c);
60 cairo_pattern_destroy(pt);
62 cairo_arc(c, xc, yc, diameter / 2, 0, 2 * M_PI);
63 cairo_set_line_width(c, 0.5);
64 cairo_set_source_rgba (c, self->led_state ? 1.0 : 0.3, 0, 0, 0.5);
65 cairo_stroke(c);
67 cairo_destroy(c);
69 return TRUE;
72 static void
73 calf_led_realize(GtkWidget *widget)
75 GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
77 GdkWindowAttr attributes;
78 attributes.event_mask = GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
79 attributes.x = widget->allocation.x;
80 attributes.y = widget->allocation.y;
81 attributes.width = widget->allocation.width;
82 attributes.height = widget->allocation.height;
83 attributes.wclass = GDK_INPUT_OUTPUT;
84 attributes.window_type = GDK_WINDOW_CHILD;
86 widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, GDK_WA_X | GDK_WA_Y);
88 gdk_window_set_user_data(widget->window, widget);
89 widget->style = gtk_style_attach(widget->style, widget->window);
92 static void
93 calf_led_size_request (GtkWidget *widget,
94 GtkRequisition *requisition)
96 g_assert(CALF_IS_LED(widget));
98 requisition->width = 12;
99 requisition->height = 12;
102 static void
103 calf_led_size_allocate (GtkWidget *widget,
104 GtkAllocation *allocation)
106 g_assert(CALF_IS_LED(widget));
108 widget->allocation = *allocation;
110 if (GTK_WIDGET_REALIZED(widget))
111 gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height );
114 static gboolean
115 calf_led_button_press (GtkWidget *widget, GdkEventButton *event)
117 return TRUE;
120 static void
121 calf_led_class_init (CalfLedClass *klass)
123 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
124 widget_class->realize = calf_led_realize;
125 widget_class->expose_event = calf_led_expose;
126 widget_class->size_request = calf_led_size_request;
127 widget_class->size_allocate = calf_led_size_allocate;
128 widget_class->button_press_event = calf_led_button_press;
131 static void
132 calf_led_init (CalfLed *self)
134 // GtkWidget *widget = GTK_WIDGET(self);
135 // GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
136 self->led_state = FALSE;
139 void calf_led_set_state(CalfLed *led, gboolean state)
141 if (state != led->led_state)
143 led->led_state = state;
144 GtkWidget *widget = GTK_WIDGET (led);
145 if (GTK_WIDGET_REALIZED(widget))
146 gtk_widget_queue_draw (widget);
150 gboolean calf_led_get_state(CalfLed *led)
152 return led->led_state;
155 GType
156 calf_led_get_type (void)
158 static GType type = 0;
159 if (!type) {
161 static const GTypeInfo type_info = {
162 sizeof(CalfLedClass),
163 NULL, /* base_init */
164 NULL, /* base_finalize */
165 (GClassInitFunc)calf_led_class_init,
166 NULL, /* class_finalize */
167 NULL, /* class_data */
168 sizeof(CalfLed),
169 0, /* n_preallocs */
170 (GInstanceInitFunc)calf_led_init
173 for (int i = 0; ; i++) {
174 char *name = g_strdup_printf("CalfLed%u%d",
175 ((unsigned int)(intptr_t)calf_led_class_init) >> 16, i);
176 if (g_type_from_name(name)) {
177 free(name);
178 continue;
180 type = g_type_register_static(GTK_TYPE_WIDGET,
181 name,
182 &type_info,
183 (GTypeFlags)0);
184 free(name);
185 break;
188 return type;