Add colour to GtkDial level meters
This commit is contained in:
@@ -125,6 +125,11 @@ struct _GtkDial {
|
|||||||
double *taper_outputs;
|
double *taper_outputs;
|
||||||
int taper_breakpoints_count;
|
int taper_breakpoints_count;
|
||||||
|
|
||||||
|
// level meter colour breakpoints array
|
||||||
|
const int *level_breakpoints;
|
||||||
|
const double *level_colours;
|
||||||
|
int level_breakpoints_count;
|
||||||
|
|
||||||
// variables derived from the widget's dynamic properties (size and
|
// variables derived from the widget's dynamic properties (size and
|
||||||
// configuration, excluding the value)
|
// configuration, excluding the value)
|
||||||
int dim;
|
int dim;
|
||||||
@@ -139,6 +144,7 @@ struct _GtkDial {
|
|||||||
double cy;
|
double cy;
|
||||||
double zero_db_x;
|
double zero_db_x;
|
||||||
double zero_db_y;
|
double zero_db_y;
|
||||||
|
double *level_breakpoint_angles;
|
||||||
|
|
||||||
// cairo patterns dependent on the above
|
// cairo patterns dependent on the above
|
||||||
cairo_pattern_t *fill_pattern[2][2];
|
cairo_pattern_t *fill_pattern[2][2];
|
||||||
@@ -374,6 +380,21 @@ static void update_dial_properties(GtkDial *dial) {
|
|||||||
|
|
||||||
dial->outline_pattern[dim] = pat;
|
dial->outline_pattern[dim] = pat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calculate level meter breakpoint angles
|
||||||
|
if (dial->level_breakpoint_angles)
|
||||||
|
free(dial->level_breakpoint_angles);
|
||||||
|
|
||||||
|
if (dial->level_breakpoints_count) {
|
||||||
|
dial->level_breakpoint_angles = malloc(
|
||||||
|
dial->level_breakpoints_count * sizeof(double)
|
||||||
|
);
|
||||||
|
for (int i = 0; i < dial->level_breakpoints_count; i++) {
|
||||||
|
double valp = calc_taper(dial, dial->level_breakpoints[i]);
|
||||||
|
dial->level_breakpoint_angles[i] =
|
||||||
|
calc_val(valp, ANGLE_START, ANGLE_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_dial_values(GtkDial *dial) {
|
static void update_dial_values(GtkDial *dial) {
|
||||||
@@ -658,10 +679,60 @@ static void draw_slider(
|
|||||||
double thickness,
|
double thickness,
|
||||||
double alpha
|
double alpha
|
||||||
) {
|
) {
|
||||||
cairo_arc(cr, dial->cx, dial->cy, radius, ANGLE_START, dial->angle);
|
|
||||||
cairo_set_line_width(cr, thickness);
|
cairo_set_line_width(cr, thickness);
|
||||||
cairo_set_source_rgba_dim(cr, 1, 1, 1, alpha, dial->dim);
|
|
||||||
cairo_stroke(cr);
|
int count = dial->level_breakpoints_count;
|
||||||
|
|
||||||
|
if (!count) {
|
||||||
|
cairo_arc(cr, dial->cx, dial->cy, radius, ANGLE_START, dial->angle);
|
||||||
|
cairo_set_source_rgba_dim(cr, 1, 1, 1, alpha, dial->dim);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the last breakpoint is at the upper limit, then the maximum
|
||||||
|
// value is displayed with the whole slider that colours
|
||||||
|
if (dial->level_breakpoint_angles[count - 1] == ANGLE_END &&
|
||||||
|
dial->angle == ANGLE_END) {
|
||||||
|
const double *colours = &dial->level_colours[(count - 1) * 3];
|
||||||
|
|
||||||
|
cairo_set_source_rgba_dim(
|
||||||
|
cr,
|
||||||
|
colours[0], colours[1], colours[2],
|
||||||
|
alpha,
|
||||||
|
dial->dim
|
||||||
|
);
|
||||||
|
|
||||||
|
cairo_arc(cr, dial->cx, dial->cy, radius, ANGLE_START, ANGLE_END);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
const double *colours = &dial->level_colours[i * 3];
|
||||||
|
|
||||||
|
cairo_set_source_rgba_dim(
|
||||||
|
cr,
|
||||||
|
colours[0], colours[1], colours[2],
|
||||||
|
alpha,
|
||||||
|
dial->dim
|
||||||
|
);
|
||||||
|
|
||||||
|
double angle_start = dial->level_breakpoint_angles[i];
|
||||||
|
double angle_end =
|
||||||
|
i == count - 1
|
||||||
|
? ANGLE_END
|
||||||
|
: dial->level_breakpoint_angles[i + 1];
|
||||||
|
|
||||||
|
if (dial->angle < angle_end) {
|
||||||
|
cairo_arc(cr, dial->cx, dial->cy, radius, angle_start, dial->angle);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_arc(cr, dial->cx, dial->cy, radius, angle_start, angle_end);
|
||||||
|
cairo_stroke(cr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dial_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) {
|
static void dial_snapshot(GtkWidget *widget, GtkSnapshot *snapshot) {
|
||||||
@@ -940,6 +1011,18 @@ gboolean gtk_dial_get_can_control(GtkDial *dial) {
|
|||||||
return dial->can_control;
|
return dial->can_control;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gtk_dial_set_level_meter_colours(
|
||||||
|
GtkDial *dial,
|
||||||
|
const int *breakpoints,
|
||||||
|
const double *colours,
|
||||||
|
int count
|
||||||
|
) {
|
||||||
|
dial->level_breakpoints = breakpoints;
|
||||||
|
dial->level_colours = colours;
|
||||||
|
dial->level_breakpoints_count = count;
|
||||||
|
dial->properties_updated = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void gtk_dial_set_adjustment(GtkDial *dial, GtkAdjustment *adj) {
|
void gtk_dial_set_adjustment(GtkDial *dial, GtkAdjustment *adj) {
|
||||||
if (!(adj == NULL || GTK_IS_ADJUSTMENT(adj)))
|
if (!(adj == NULL || GTK_IS_ADJUSTMENT(adj)))
|
||||||
return;
|
return;
|
||||||
@@ -1217,6 +1300,8 @@ void gtk_dial_dispose(GObject *o) {
|
|||||||
free(dial->taper_outputs);
|
free(dial->taper_outputs);
|
||||||
dial->taper_outputs = NULL;
|
dial->taper_outputs = NULL;
|
||||||
dial->taper_breakpoints_count = 0;
|
dial->taper_breakpoints_count = 0;
|
||||||
|
free(dial->level_breakpoint_angles);
|
||||||
|
dial->level_breakpoint_angles = NULL;
|
||||||
|
|
||||||
for (int focus = 0; focus <= 1; focus++)
|
for (int focus = 0; focus <= 1; focus++)
|
||||||
for (int dim = 0; dim <= 1; dim++)
|
for (int dim = 0; dim <= 1; dim++)
|
||||||
|
|||||||
@@ -87,6 +87,13 @@ void gtk_dial_set_taper_linear_breakpoints(
|
|||||||
void gtk_dial_set_can_control(GtkDial *dial, gboolean can_control);
|
void gtk_dial_set_can_control(GtkDial *dial, gboolean can_control);
|
||||||
gboolean gtk_dial_get_can_control(GtkDial *dial);
|
gboolean gtk_dial_get_can_control(GtkDial *dial);
|
||||||
|
|
||||||
|
void gtk_dial_set_level_meter_colours(
|
||||||
|
GtkDial *dial,
|
||||||
|
const int *breakpoints,
|
||||||
|
const double *colours,
|
||||||
|
int count
|
||||||
|
);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,6 +9,20 @@
|
|||||||
#include "widget-gain.h"
|
#include "widget-gain.h"
|
||||||
#include "window-levels.h"
|
#include "window-levels.h"
|
||||||
|
|
||||||
|
static const int level_breakpoints_out[] = { -80, -18, -12, -6, -3, -1 };
|
||||||
|
|
||||||
|
// inputs glow all-red when limit is reached
|
||||||
|
static const int level_breakpoints_in[] = { -80, -18, -12, -6, -3, 0 };
|
||||||
|
|
||||||
|
static const double level_colours[] = {
|
||||||
|
0.00, 1.00, 0.00, // -80
|
||||||
|
0.75, 1.00, 0.00, // -18
|
||||||
|
1.00, 1.00, 0.00, // -12
|
||||||
|
1.00, 0.75, 0.00, // -6
|
||||||
|
1.00, 0.50, 0.00, // -3
|
||||||
|
1.00, 0.00, 0.00 // -1/0
|
||||||
|
};
|
||||||
|
|
||||||
static int update_levels_controls(void *user_data) {
|
static int update_levels_controls(void *user_data) {
|
||||||
struct alsa_card *card = user_data;
|
struct alsa_card *card = user_data;
|
||||||
|
|
||||||
@@ -104,6 +118,14 @@ GtkWidget *create_levels_controls(struct alsa_card *card) {
|
|||||||
GtkWidget *meter = gtk_dial_new_with_range(-80, 0, 0, 0);
|
GtkWidget *meter = gtk_dial_new_with_range(-80, 0, 0, 0);
|
||||||
gtk_dial_set_taper(GTK_DIAL(meter), GTK_DIAL_TAPER_LINEAR);
|
gtk_dial_set_taper(GTK_DIAL(meter), GTK_DIAL_TAPER_LINEAR);
|
||||||
gtk_dial_set_can_control(GTK_DIAL(meter), FALSE);
|
gtk_dial_set_can_control(GTK_DIAL(meter), FALSE);
|
||||||
|
gtk_dial_set_level_meter_colours(
|
||||||
|
GTK_DIAL(meter),
|
||||||
|
(i == PC_DSP || i == PC_PCM)
|
||||||
|
? level_breakpoints_in
|
||||||
|
: level_breakpoints_out,
|
||||||
|
level_colours,
|
||||||
|
sizeof(level_breakpoints_out) / sizeof(int)
|
||||||
|
);
|
||||||
gtk_widget_set_sensitive(meter, FALSE);
|
gtk_widget_set_sensitive(meter, FALSE);
|
||||||
|
|
||||||
// HW Output off_db is -55db; otherwise -45db
|
// HW Output off_db is -55db; otherwise -45db
|
||||||
|
|||||||
Reference in New Issue
Block a user