1 /* B.Shapr
2 * Beat / envelope shaper LV2 plugin
3 *
4 * Copyright (C) 2019 by Sven Jähnichen
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
10 *
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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include "MonitorWidget.hpp"
22 #include <cmath>
23
MonitorWidget()24 MonitorWidget::MonitorWidget () : MonitorWidget (0, 0, 0, 0, "monitor") {}
25
MonitorWidget(const double x,const double y,const double width,const double height,const std::string & name)26 MonitorWidget::MonitorWidget (const double x, const double y, const double width, const double height, const std::string& name) :
27 Widget (x, y, width, height, name),
28 fgColors (BColors::whites), zoom (0.25), pat (nullptr)
29 {
30 clear ();
31 setClickable (false);
32 makePattern ();
33 }
34
~MonitorWidget()35 MonitorWidget::~MonitorWidget ()
36 {
37 if (pat) cairo_pattern_destroy (pat);
38 }
39
clear()40 void MonitorWidget::clear () {data.fill ({0.0f, 0.0f});}
41
addData(const unsigned int pos,const Range range)42 void MonitorWidget::addData (const unsigned int pos, const Range range)
43 {
44 unsigned int nr = LIMIT (pos, 0, MONITORBUFFERSIZE - 1);
45 data[nr] = range;
46 }
47
setZoom(const double factor)48 void MonitorWidget::setZoom (const double factor)
49 {
50 zoom = factor;
51 update ();
52 }
getZoom() const53 double MonitorWidget::getZoom () const {return zoom;}
54
redrawRange(const unsigned int start,const unsigned int end)55 void MonitorWidget::redrawRange (const unsigned int start, const unsigned int end)
56 {
57 unsigned int s = LIMIT (int (start) - 1, 0, MONITORBUFFERSIZE - 1);
58 unsigned int e = LIMIT (end + 1, 0, MONITORBUFFERSIZE - 1);
59 double xabs = getAbsolutePosition().x;
60 double yabs = getAbsolutePosition().y;
61 double x1 = getWidth() * s / (MONITORBUFFERSIZE - 1);
62 double w = getWidth() * (e - s) / (MONITORBUFFERSIZE - 1);
63
64 drawData (s, e);
65 if (isVisible ()) postRedisplay (BUtilities::RectArea (xabs + x1, yabs, w, getHeight()));
66 }
67
applyTheme(BStyles::Theme & theme)68 void MonitorWidget::applyTheme (BStyles::Theme& theme) {applyTheme (theme, name_);}
69
applyTheme(BStyles::Theme & theme,const std::string & name)70 void MonitorWidget::applyTheme (BStyles::Theme& theme, const std::string& name)
71 {
72 Widget::applyTheme (theme, name);
73
74 void* fgPtr = theme.getStyle(name, BWIDGETS_KEYWORD_FGCOLORS);
75 if (fgPtr)
76 {
77 fgColors = *((BColors::ColorSet*) fgPtr);
78 update ();
79 }
80 }
81
update()82 void MonitorWidget::update ()
83 {
84 makePattern ();
85 Widget::update ();
86 }
87
makePattern()88 void MonitorWidget::makePattern ()
89 {
90 if (pat) cairo_pattern_destroy (pat);
91 pat = cairo_pattern_create_linear (0, 0, 0, getHeight());
92 BColors::Color col = *fgColors.getColor (getState ());
93 cairo_pattern_add_color_stop_rgba (pat, 1, col.getRed (), col.getGreen (), col.getBlue (), 0.6 * col.getAlpha ());
94 cairo_pattern_add_color_stop_rgba (pat, 0.5, col.getRed (), col.getGreen (), col.getBlue (), 0.1 * col.getAlpha ());
95 cairo_pattern_add_color_stop_rgba (pat, 0, col.getRed (), col.getGreen (), col.getBlue (), 0.6 * col.getAlpha ());
96 }
97
drawData(const unsigned int start,const unsigned int end)98 void MonitorWidget::drawData (const unsigned int start, const unsigned int end)
99 {
100 if ((!widgetSurface_) || (cairo_surface_status (widgetSurface_) != CAIRO_STATUS_SUCCESS)) return;
101
102 BColors::Color col = *fgColors.getColor (getState ());
103 cairo_t* cr = cairo_create (widgetSurface_);
104
105 if (cairo_status (cr) == CAIRO_STATUS_SUCCESS)
106 {
107 // Limit cairo-drawing area
108 cairo_set_line_width (cr, 0);
109 double x0 = ceil (getWidth() * start / (MONITORBUFFERSIZE - 1));
110 double x1 = floor (getWidth() * end / (MONITORBUFFERSIZE - 1));
111 cairo_rectangle (cr, x0, 0, x1 - x0, getHeight());
112 cairo_clip (cr);
113
114 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
115 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
116 cairo_paint (cr);
117
118 cairo_set_line_width (cr, 2);
119 cairo_move_to (cr, getWidth() * double (start) / (MONITORBUFFERSIZE - 1), getHeight() * (0.5 - (0.48 * LIMIT ((data[start].max / zoom), -1, 1))));
120 for (int i = start + 1; i <= int (end); ++i)
121 {
122 cairo_line_to (cr, getWidth() * double (i) / (MONITORBUFFERSIZE - 1), getHeight() * (0.5 - (0.48 * LIMIT ((data[i].max / zoom), -1, 1))));
123 }
124 cairo_set_source_rgba (cr, CAIRO_RGBA (col));
125 cairo_stroke_preserve (cr);
126 cairo_set_line_width (cr, 0);
127 cairo_line_to (cr, getWidth() * double (end) / (MONITORBUFFERSIZE - 1), getHeight() * 0.5);
128 cairo_line_to (cr, getWidth() * double (start) / (MONITORBUFFERSIZE - 1), getHeight() * 0.5);
129 cairo_close_path (cr);
130 cairo_set_source (cr, pat);
131 cairo_fill (cr);
132
133 cairo_set_line_width (cr, 2);
134 cairo_move_to (cr, getWidth() * double (start) / (MONITORBUFFERSIZE - 1), getHeight() * (0.5 - (0.48 * LIMIT ((data[start].min / zoom), -1, 1))));
135 for (int i = start + 1; i <= int (end); ++i)
136 {
137 cairo_line_to (cr, getWidth() * double (i) / (MONITORBUFFERSIZE - 1), getHeight() * (0.5 - (0.48 * LIMIT ((data[i].min / zoom), -1, 1))));
138 }
139 cairo_set_source_rgba (cr, CAIRO_RGBA (col));
140 cairo_stroke_preserve (cr);
141 cairo_set_line_width (cr, 0);
142 cairo_line_to (cr, getWidth() * double (end) / (MONITORBUFFERSIZE - 1), getHeight() * 0.5);
143 cairo_line_to (cr, getWidth() * double (start) / (MONITORBUFFERSIZE - 1), getHeight() * 0.5);
144 cairo_close_path (cr);
145 cairo_set_source (cr, pat);
146 cairo_fill (cr);
147
148 cairo_destroy (cr);
149 }
150 }
151
draw(const BUtilities::RectArea & area)152 void MonitorWidget::draw (const BUtilities::RectArea& area)
153 {
154 drawData (0, MONITORBUFFERSIZE - 1);
155 }
156