uint32_t text_color;
uint32_t led_color;
+ const float corner_radius = std::max(2.f, _corner_radius * ARDOUR_UI::ui_scale);
+
if (_update_colors) {
set_colors ();
}
// draw edge (filling a rect underneath, rather than stroking a border on top, allows the corners to be lighter-weight.
if ((_elements & (Body|Edge)) == (Body|Edge)) {
- rounded_function (cr, 0, 0, get_width(), get_height(), _corner_radius + 1.5);
+ rounded_function (cr, 0, 0, get_width(), get_height(), corner_radius + 1.5);
cairo_set_source_rgba (cr, 0, 0, 0, 1);
cairo_fill(cr);
}
// background fill
if ((_elements & Body)==Body) {
- rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius);
+ rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius);
if (active_state() == Gtkmm2ext::ImplicitActive && !((_elements & Indicator)==Indicator)) {
ArdourCanvas::set_source_rgba (cr, fill_inactive_color);
cairo_fill (cr);
if ((_elements & Body)==Body) {
if (active_state() == Gtkmm2ext::ImplicitActive && !((_elements & Indicator)==Indicator)) {
cairo_set_line_width (cr, 2.0);
- rounded_function (cr, 2, 2, get_width() - 4, get_height() - 4, _corner_radius-0.5);
+ rounded_function (cr, 2, 2, get_width() - 4, get_height() - 4, corner_radius-0.5);
ArdourCanvas::set_source_rgba (cr, fill_active_color);
cairo_stroke (cr);
}
if ( active_state() == Gtkmm2ext::ExplicitActive && ( !((_elements & Indicator)==Indicator) || use_custom_led_color) ) {
//concave
cairo_set_source (cr, concave_pattern);
- Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius);
+ Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius);
cairo_fill (cr);
} else {
cairo_set_source (cr, convex_pattern);
- Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius);
+ Gtkmm2ext::rounded_rectangle (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius);
cairo_fill (cr);
}
}
-#define VECTORICONSTROKEFILL \
+#define VECTORICONSTROKEFILL(fillalpha) \
cairo_set_line_width(cr, 1.5); \
cairo_set_source_rgba (cr, 0, 0, 0, 1.0); \
cairo_stroke_preserve(cr); \
- cairo_set_source_rgba (cr, 1, 1, 1, 1.0); \
+ cairo_set_source_rgba (cr, 1, 1, 1, (fillalpha)); \
cairo_fill(cr);
//Pixbuf, if any
gdk_cairo_set_source_pixbuf (cr, _pixbuf->gobj(), x, y);
cairo_fill (cr);
}
- else // rec-en is exclusive to pixbuf (tape machine mode, rec-en)
+ else /* VectorIcons are exclusive to Pixbuf Icons */
+ /* TODO separate these into dedicated class
+ * it may also be efficient to render them only once for every size (image-surface) */
if ((_elements & VectorIcon) && _icon == RecTapeMode) {
const double x = get_width() * .5;
const double y = get_height() * .5;
- const double r = std::min(10., std::min(x, y) * .6); // TODO we need a better way to limit max. radius.
+ const double r = std::min(x, y) * .6;
const double slit = .11 * M_PI;
cairo_save(cr);
cairo_translate(cr, x, y);
cairo_arc (cr, 0, 0, r, 0, 2 * M_PI);
- if (active_state() == Gtkmm2ext::ExplicitActive)
+ if (active_state() == Gtkmm2ext::ExplicitActive) {
cairo_set_source_rgba (cr, .95, .1, .1, 1.);
- else
+ } else {
cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f
+ }
cairo_fill_preserve(cr);
cairo_set_source_rgba (cr, .0, .0, .0, .5);
cairo_set_line_width(cr, 1);
else if ((_elements & VectorIcon) && _icon == RecButton) {
const double x = get_width() * .5;
const double y = get_height() * .5;
- const double r = std::min(10., std::min(x, y) * .55); // TODO we need a better way to limit max. radius.
+ const double r = std::min(x, y) * .55;
cairo_arc (cr, x, y, r, 0, 2 * M_PI);
if (active_state() == Gtkmm2ext::ExplicitActive)
cairo_set_source_rgba (cr, .95, .1, .1, 1.);
cairo_arc (cr, x, y+r, r * .28, 1.05 * M_PI, 1.95 * M_PI);
cairo_stroke(cr);
}
- else if ((_elements & VectorIcon) && _icon == BtnStop) {
+ else if ((_elements & VectorIcon) && _icon == TransportStop) {
const int wh = std::min (get_width(), get_height());
cairo_rectangle (cr,
(get_width() - wh) * .5 + wh * .25,
(get_height() - wh) * .5 + wh * .25,
wh * .5, wh * .5);
- VECTORICONSTROKEFILL;
+ VECTORICONSTROKEFILL(0.8);
}
- else if ((_elements & VectorIcon) && _icon == BtnPlay) {
+ else if ((_elements & VectorIcon) && _icon == TransportPlay) {
const int wh = std::min (get_width(), get_height()) * .5;
const double y = get_height() * .5;
const double x = get_width() - wh;
cairo_line_to (cr, x - wh * .5, y + tri);
cairo_close_path (cr);
- VECTORICONSTROKEFILL;
+ VECTORICONSTROKEFILL(0.8);
}
- else if ((_elements & VectorIcon) && _icon == BtnPanic) {
+ else if ((_elements & VectorIcon) && _icon == TransportPanic) {
const int wh = std::min (get_width(), get_height()) * .1;
const double xc = get_width() * .5;
const double yh = get_height();
cairo_rectangle (cr,
xc - wh, yh *.2,
wh * 2, yh *.4);
- VECTORICONSTROKEFILL;
+ VECTORICONSTROKEFILL(0.8);
cairo_arc (cr, xc, yh *.75, wh, 0, 2 * M_PI);
- VECTORICONSTROKEFILL;
+ VECTORICONSTROKEFILL(0.8);
}
- else if ((_elements & VectorIcon) && (_icon == BtnStart || _icon == BtnEnd || _icon == BtnRange)) {
+ else if ((_elements & VectorIcon) && (_icon == TransportStart || _icon == TransportEnd || _icon == TransportRange)) {
// small play triangle
int wh = std::min (get_width(), get_height());
const double y = get_height() * .5;
const float ln = std::min (get_width(), get_height()) * .07;
- if (_icon == BtnStart || _icon == BtnRange) {
+ if (_icon == TransportStart || _icon == TransportRange) {
cairo_rectangle (cr,
- x - wh - ln, y - tri * 1.7,
- ln * 2, tri * 3.4);
+ x - wh - ln, y - tri * 1.7,
+ ln * 2, tri * 3.4);
- VECTORICONSTROKEFILL;
+ VECTORICONSTROKEFILL(1.0);
}
- if (_icon == BtnEnd || _icon == BtnRange) {
+ if (_icon == TransportEnd || _icon == TransportRange) {
cairo_rectangle (cr,
- x + wh - ln, y - tri * 1.7,
- ln * 2, tri * 3.4);
+ x + wh - ln, y - tri * 1.7,
+ ln * 2, tri * 3.4);
+
+ VECTORICONSTROKEFILL(1.0);
+ }
- VECTORICONSTROKEFILL;
+ if (_icon == TransportStart) {
+ cairo_move_to (cr, x - wh, y);
+ cairo_line_to (cr, x + wh, y - tri);
+ cairo_line_to (cr, x + wh, y + tri);
+ } else {
+ cairo_move_to (cr, x + wh, y);
+ cairo_line_to (cr, x - wh, y - tri);
+ cairo_line_to (cr, x - wh, y + tri);
}
- cairo_move_to (cr, x + wh, y);
- cairo_line_to (cr, x - wh, y - tri);
- cairo_line_to (cr, x - wh, y + tri);
+ cairo_close_path (cr);
+ VECTORICONSTROKEFILL(1.0);
+ }
+ else if ((_elements & VectorIcon) && _icon == TransportLoop) {
+ const double x = get_width() * .5;
+ const double y = get_height() * .5;
+ const double r = std::min(x, y);
+
+ cairo_arc (cr, x, y, r * .6, 0, 2 * M_PI);
+ cairo_arc_negative (cr, x, y, r * .3, 2 * M_PI, 0);
+
+ VECTORICONSTROKEFILL(1.0);
+#define ARCARROW(rad, ang) \
+ x + (rad) * sin((ang) * 2.0 * M_PI), y + (rad) * cos((ang) * 2.0 * M_PI)
+
+ cairo_move_to (cr, ARCARROW(r * .30, .72));
+ cairo_line_to (cr, ARCARROW(r * .08, .72));
+ cairo_line_to (cr, ARCARROW(r * .54, .60));
+ cairo_line_to (cr, ARCARROW(r * .73, .72));
+ cairo_line_to (cr, ARCARROW(r * .60, .72));
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 1.0);
+ cairo_stroke_preserve(cr);
+ cairo_close_path (cr);
+ cairo_set_source_rgba (cr, 1, 1, 1, 1.0);
+ cairo_fill(cr);
+#undef ARCARROW
+ }
+ else if ((_elements & VectorIcon) && _icon == TransportMetronom) {
+ const double x = get_width() * .5;
+ const double y = get_height() * .5;
+ const double wh = std::min(x, y);
+ const double h = wh * .8;
+ const double w = wh * .5;
+ const double lw = w * .25;
+
+ cairo_rectangle (cr,
+ x - w * .7, y + h * .25,
+ w * 1.4, lw);
+
+ VECTORICONSTROKEFILL(1.0);
+
+ cairo_move_to (cr, x - w, y + h);
+ cairo_line_to (cr, x + w, y + h);
+ cairo_line_to (cr, x + w * .35, y - h);
+ cairo_line_to (cr, x - w * .35, y - h);
+ cairo_line_to (cr, x - w, y + h);
+
+ cairo_move_to (cr, x - w + lw, y + h -lw);
+ cairo_line_to (cr, x - w * .35 + lw, y - h + lw);
+ cairo_line_to (cr, x + w * .35 - lw, y - h + lw);
+ cairo_line_to (cr, x + w - lw, y + h -lw);
+ cairo_line_to (cr, x - w + lw, y + h -lw);
+
+ VECTORICONSTROKEFILL(1.0);
+
+ // ddx = .70 w = .75 * .5 wh = .375 wh
+ // ddy = .75 h - lw = .75 * .8 wh - wh .5 * .2 = .5 wh
+ // ang = (ddx/ddy):
+ // -> angle = atan (ang) = atan (375 / .5) ~= 36deg
+ const double dx = lw * .2; // 1 - cos(tan^-1(ang))
+ const double dy = lw * .4; // 1 - sin(tan^-1(ang))
+ cairo_move_to (cr, x - w * .3 , y + h * .25 + lw * .5);
+ cairo_line_to (cr, x - w + dx , y - h + lw + dy);
+ cairo_line_to (cr, x - w + lw , y - h + lw);
+ cairo_line_to (cr, x - w * .3 + lw, y + h * .25 + lw * .5);
cairo_close_path (cr);
- VECTORICONSTROKEFILL;
+ VECTORICONSTROKEFILL(1.0);
+
+ cairo_rectangle (cr,
+ x - w * .7, y + h * .25,
+ w * 1.4, lw);
+ cairo_fill(cr);
}
else if (_elements & VectorIcon) {
// missing icon
assert(0);
}
+#undef VECTORICONSTROKEFILL
const int text_margin = char_pixel_width();
// Text, if any
//black ring
cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_arc (cr, 0, 0, _diameter * .5 - 1, 0, 2 * M_PI);
+ cairo_arc (cr, 0, 0, _diameter * .5 - 1 * ARDOUR_UI::ui_scale, 0, 2 * M_PI);
cairo_fill(cr);
//led color
ArdourCanvas::set_source_rgba (cr, led_color);
- cairo_arc (cr, 0, 0, _diameter * .5 - 3, 0, 2 * M_PI);
+ cairo_arc (cr, 0, 0, _diameter * .5 - 3 * ARDOUR_UI::ui_scale, 0, 2 * M_PI);
cairo_fill(cr);
cairo_restore (cr);
// a transparent overlay to indicate insensitivity
if ((visual_state() & Gtkmm2ext::Insensitive)) {
- rounded_function (cr, 0, 0, get_width(), get_height(), _corner_radius);
+ rounded_function (cr, 0, 0, get_width(), get_height(), corner_radius);
uint32_t ins_color = ARDOUR_UI::config()->color ("gtk_background");
ArdourCanvas::set_source_rgb_a (cr, ins_color, 0.6);
cairo_fill (cr);
if (ARDOUR_UI::config()->get_widget_prelight()
&& !((visual_state() & Gtkmm2ext::Insensitive))) {
if (_hovering) {
- rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius);
+ rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius);
cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.2);
cairo_fill (cr);
}
//user is currently pressing the button. dark outline helps to indicate this
if (_grabbed && !(_elements & (Inactive|Menu))) {
- rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, _corner_radius);
+ rounded_function (cr, 1, 1, get_width() - 2, get_height() - 2, corner_radius);
cairo_set_line_width(cr, 2);
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, .5);
cairo_stroke (cr);
if (visual_state() & Gtkmm2ext::Selected) {
cairo_set_line_width(cr, 1);
cairo_set_source_rgba (cr, 1, 0, 0, 0.8);
- rounded_function (cr, 0.5, 0.5, get_width() - 1, get_height() - 1, _corner_radius);
+ rounded_function (cr, 0.5, 0.5, get_width() - 1, get_height() - 1, corner_radius);
cairo_stroke (cr);
}
// (the editor is always the first receiver for KeyDown).
// It's needed for eg. the engine-dialog at startup or after closing a sesion.
if (_focused) {
- rounded_function (cr, 1.5, 1.5, get_width() - 3, get_height() - 3, _corner_radius);
+ rounded_function (cr, 1.5, 1.5, get_width() - 3, get_height() - 3, corner_radius);
cairo_set_source_rgba (cr, 0.905, 0.917, 0.925, 0.8);
double dashes = 1;
cairo_set_dash (cr, &dashes, 1, 0);
CairoWidget::on_size_request (req);
if (_diameter == 0) {
- const float newdia = rint (ARDOUR_UI::config()->get_font_scale () / 9600.0); // 11px with 100% font-scaling
+ const float newdia = rintf (11.f * ARDOUR_UI::ui_scale);
if (_diameter != newdia) {
_pattern_height = 0;
_diameter = newdia;