+ DSP primitives: fix a rather stupid bug in clamping functions
[calf.git] / src / ctl_led.cpp
blob3626d9a12217208a080de56bb019138ef83525f0
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., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 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 ox = 2;
47 int oy = 2;
48 int sx = widget->allocation.width - 4;
49 int sy = widget->allocation.height - 4;
50 int xc = widget->allocation.width / 2;
51 int yc = widget->allocation.height / 2;
53 cairo_pattern_t *pt = cairo_pattern_create_radial(xc, yc, 0, xc, yc, xc > yc ? xc : yc);
54 cairo_pattern_add_color_stop_rgb(pt, 0.0, self->led_state ? 0.2 : 0.0, self->led_state ? 0.7 : 0.25, self->led_state ? 1.0 : 0.5);
55 cairo_pattern_add_color_stop_rgb(pt, 0.5, self->led_state ? 0.1 : 0.0, self->led_state ? 0.5 : 0.15, self->led_state ? 0.75 : 0.3);
56 cairo_pattern_add_color_stop_rgb(pt, 1.0, 0.0, self->led_state ? 0.3 : 0.1, self->led_state ? 0.5 : 0.2);
58 cairo_rectangle(c, ox, oy, sx, sy);
59 cairo_set_source (c, pt);
60 cairo_fill(c);
61 cairo_pattern_destroy(pt);
63 cairo_rectangle(c, ox + 0.5, oy + 0.5, sx - 1, sy - 1);
64 cairo_set_source_rgb(c, 0, 0, 0);
65 cairo_set_line_width(c, 1);
66 cairo_stroke(c);
68 gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, ox - 2, oy - 2, sx + 4, sy + 4);
70 cairo_destroy(c);
72 return TRUE;
75 static void
76 calf_led_realize(GtkWidget *widget)
78 GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
80 GdkWindowAttr attributes;
81 attributes.event_mask = GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
82 attributes.x = widget->allocation.x;
83 attributes.y = widget->allocation.y;
84 attributes.width = widget->allocation.width;
85 attributes.height = widget->allocation.height;
86 attributes.wclass = GDK_INPUT_OUTPUT;
87 attributes.window_type = GDK_WINDOW_CHILD;
89 widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, GDK_WA_X | GDK_WA_Y);
91 gdk_window_set_user_data(widget->window, widget);
92 widget->style = gtk_style_attach(widget->style, widget->window);
95 static void
96 calf_led_size_request (GtkWidget *widget,
97 GtkRequisition *requisition)
99 g_assert(CALF_IS_LED(widget));
101 requisition->width = 22;
102 requisition->height = 16;
105 static void
106 calf_led_size_allocate (GtkWidget *widget,
107 GtkAllocation *allocation)
109 g_assert(CALF_IS_LED(widget));
111 widget->allocation = *allocation;
113 if (GTK_WIDGET_REALIZED(widget))
114 gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height );
117 static gboolean
118 calf_led_button_press (GtkWidget *widget, GdkEventButton *event)
120 return TRUE;
123 static void
124 calf_led_class_init (CalfLedClass *klass)
126 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
127 widget_class->realize = calf_led_realize;
128 widget_class->expose_event = calf_led_expose;
129 widget_class->size_request = calf_led_size_request;
130 widget_class->size_allocate = calf_led_size_allocate;
131 widget_class->button_press_event = calf_led_button_press;
134 static void
135 calf_led_init (CalfLed *self)
137 // GtkWidget *widget = GTK_WIDGET(self);
138 // GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
139 self->led_state = FALSE;
142 void calf_led_set_state(CalfLed *led, gboolean state)
144 if (state != led->led_state)
146 led->led_state = state;
147 GtkWidget *widget = GTK_WIDGET (led);
148 if (GTK_WIDGET_REALIZED(widget))
149 gtk_widget_queue_draw (widget);
153 gboolean calf_led_get_state(CalfLed *led)
155 return led->led_state;
158 GType
159 calf_led_get_type (void)
161 static GType type = 0;
162 if (!type) {
163 static const GTypeInfo type_info = {
164 sizeof(CalfLedClass),
165 NULL, /* base_init */
166 NULL, /* base_finalize */
167 (GClassInitFunc)calf_led_class_init,
168 NULL, /* class_finalize */
169 NULL, /* class_data */
170 sizeof(CalfLed),
171 0, /* n_preallocs */
172 (GInstanceInitFunc)calf_led_init
175 for (int i = 0; ; i++) {
176 char *name = g_strdup_printf("CalfLed%u%d",
177 ((unsigned int)(intptr_t)calf_led_class_init) >> 16, i);
178 if (g_type_from_name(name)) {
179 free(name);
180 continue;
182 type = g_type_register_static(GTK_TYPE_WIDGET,
183 name,
184 &type_info,
185 (GTypeFlags)0);
186 free(name);
187 break;
190 return type;