New LED mode (red)
[calf.git] / src / ctl_led.cpp
blob4eba021bea6992cf9c9e42cf9c8dd0bd1176ee67
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 switch (self->led_mode) {
55 default:
56 case 0:
57 cairo_pattern_add_color_stop_rgb(pt, 0.0, self->led_state ? 0.2 : 0.0, self->led_state ? 1.0 : 0.25, self->led_state ? 1.0 : 0.5);
58 cairo_pattern_add_color_stop_rgb(pt, 0.5, self->led_state ? 0.1 : 0.0, self->led_state ? 0.6 : 0.15, self->led_state ? 0.75 : 0.3);
59 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);
60 break;
61 case 1:
62 cairo_pattern_add_color_stop_rgb(pt, 0.0, self->led_state ? 1.0 : 0.5, self->led_state ? 0.5 : 0.0, self->led_state ? 0.2 : 0.0);
63 cairo_pattern_add_color_stop_rgb(pt, 0.5, self->led_state ? 0.75 : 0.3, self->led_state ? 0.2 : 0.0, self->led_state ? 0.1 : 0.0);
64 cairo_pattern_add_color_stop_rgb(pt, 1.0, self->led_state ? 0.5 : 0.2, self->led_state ? 0.1 : 0.0, 0.0);
65 break;
68 cairo_rectangle(c, ox, oy, sx, sy);
69 cairo_set_source (c, pt);
70 cairo_fill(c);
71 cairo_pattern_destroy(pt);
73 cairo_rectangle(c, ox + 0.5, oy + 0.5, sx - 1, sy - 1);
74 cairo_set_source_rgb(c, 0, 0, 0);
75 cairo_set_line_width(c, 1);
76 cairo_stroke(c);
78 gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, ox - 2, oy - 2, sx + 4, sy + 4);
80 cairo_destroy(c);
82 return TRUE;
85 static void
86 calf_led_realize(GtkWidget *widget)
88 GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
90 GdkWindowAttr attributes;
91 attributes.event_mask = GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK;
92 attributes.x = widget->allocation.x;
93 attributes.y = widget->allocation.y;
94 attributes.width = widget->allocation.width;
95 attributes.height = widget->allocation.height;
96 attributes.wclass = GDK_INPUT_OUTPUT;
97 attributes.window_type = GDK_WINDOW_CHILD;
99 widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, GDK_WA_X | GDK_WA_Y);
101 gdk_window_set_user_data(widget->window, widget);
102 widget->style = gtk_style_attach(widget->style, widget->window);
105 static void
106 calf_led_size_request (GtkWidget *widget,
107 GtkRequisition *requisition)
109 g_assert(CALF_IS_LED(widget));
111 requisition->width = 22;
112 requisition->height = 16;
115 static void
116 calf_led_size_allocate (GtkWidget *widget,
117 GtkAllocation *allocation)
119 g_assert(CALF_IS_LED(widget));
121 widget->allocation = *allocation;
123 if (GTK_WIDGET_REALIZED(widget))
124 gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height );
127 static gboolean
128 calf_led_button_press (GtkWidget *widget, GdkEventButton *event)
130 return TRUE;
133 static void
134 calf_led_class_init (CalfLedClass *klass)
136 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
137 widget_class->realize = calf_led_realize;
138 widget_class->expose_event = calf_led_expose;
139 widget_class->size_request = calf_led_size_request;
140 widget_class->size_allocate = calf_led_size_allocate;
141 widget_class->button_press_event = calf_led_button_press;
144 static void
145 calf_led_init (CalfLed *self)
147 // GtkWidget *widget = GTK_WIDGET(self);
148 // GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
149 self->led_state = FALSE;
152 void calf_led_set_state(CalfLed *led, gboolean state)
154 if (state != led->led_state)
156 led->led_state = state;
157 GtkWidget *widget = GTK_WIDGET (led);
158 if (GTK_WIDGET_REALIZED(widget))
159 gtk_widget_queue_draw (widget);
163 gboolean calf_led_get_state(CalfLed *led)
165 return led->led_state;
168 GType
169 calf_led_get_type (void)
171 static GType type = 0;
172 if (!type) {
173 static const GTypeInfo type_info = {
174 sizeof(CalfLedClass),
175 NULL, /* base_init */
176 NULL, /* base_finalize */
177 (GClassInitFunc)calf_led_class_init,
178 NULL, /* class_finalize */
179 NULL, /* class_data */
180 sizeof(CalfLed),
181 0, /* n_preallocs */
182 (GInstanceInitFunc)calf_led_init
185 for (int i = 0; ; i++) {
186 char *name = g_strdup_printf("CalfLed%u%d",
187 ((unsigned int)(intptr_t)calf_led_class_init) >> 16, i);
188 if (g_type_from_name(name)) {
189 free(name);
190 continue;
192 type = g_type_register_static(GTK_TYPE_WIDGET,
193 name,
194 &type_info,
195 (GTypeFlags)0);
196 free(name);
197 break;
200 return type;