|
| 1 | +/* |
| 2 | + * Copyright (C) 2025 Linux Studio Plugins Project <https://lsp-plug.in/> |
| 3 | + * (C) 2025 Vladimir Sadovnikov <sadko4u@gmail.com> |
| 4 | + * |
| 5 | + * This file is part of lsp-tk-lib |
| 6 | + * Created on: 3 июн. 2025 г. |
| 7 | + * |
| 8 | + * lsp-tk-lib is free software: you can redistribute it and/or modify |
| 9 | + * it under the terms of the GNU Lesser General Public License as published by |
| 10 | + * the Free Software Foundation, either version 3 of the License, or |
| 11 | + * any later version. |
| 12 | + * |
| 13 | + * lsp-tk-lib is distributed in the hope that it will be useful, |
| 14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | + * GNU Lesser General Public License for more details. |
| 17 | + * |
| 18 | + * You should have received a copy of the GNU Lesser General Public License |
| 19 | + * along with lsp-tk-lib. If not, see <https://www.gnu.org/licenses/>. |
| 20 | + */ |
| 21 | + |
| 22 | +#ifndef LSP_PLUG_IN_TK_WIDGETS_SPECIFIC_AUDIOENVELOPE_H_ |
| 23 | +#define LSP_PLUG_IN_TK_WIDGETS_SPECIFIC_AUDIOENVELOPE_H_ |
| 24 | + |
| 25 | +#ifndef LSP_PLUG_IN_TK_IMPL |
| 26 | + #error "use <lsp-plug.in/tk/tk.h>" |
| 27 | +#endif |
| 28 | + |
| 29 | +namespace lsp |
| 30 | +{ |
| 31 | + namespace tk |
| 32 | + { |
| 33 | + class AudioSample; |
| 34 | + |
| 35 | + // Style definition |
| 36 | + namespace style |
| 37 | + { |
| 38 | + LSP_TK_STYLE_DEF_BEGIN(AudioEnvelope, Widget) |
| 39 | + prop::Float sAttackTime; // Normalized attack time [0..1] |
| 40 | + prop::Float sAttackCurvature; // Normalized attack curvature [0..1] |
| 41 | + prop::StepFloat sAttackStep; // Attack curvature step |
| 42 | + prop::Float sHoldTime; // Normalized Hold time point [0..1] |
| 43 | + prop::Float sDecayTime; // Normalized Decay time point [0..1] |
| 44 | + prop::Float sDecayCurvature; // Normalized Decay curvature [0..1] |
| 45 | + prop::StepFloat sDecayStep; // Decay curvature step |
| 46 | + prop::Float sBreakLevel; // Normalized Break level point [0..1] |
| 47 | + prop::Float sSlopeTime; // Normalized Slope time point [0..1] |
| 48 | + prop::Float sSlopeCurvature; // Normalized Slope curvature [0..1] |
| 49 | + prop::StepFloat sSlopeStep; // Slope curvature step |
| 50 | + prop::Float sSustainLevel; // Normalized Sustain level [0..1] |
| 51 | + prop::Float sReleaseTime; // Normalized Release time [0..1] |
| 52 | + prop::Float sReleaseCurvature; // Normalized Release slope [0..1] |
| 53 | + prop::StepFloat sReleaseStep; // Release slope step |
| 54 | + prop::Boolean sHold; // Enable hold time point |
| 55 | + prop::Boolean sBreak; // Enable slope time point |
| 56 | + prop::Boolean sQuadPoint; // Use quad point instead of circle |
| 57 | + prop::Boolean sInvertMouseVScroll; // Invert mouse vertical scroll |
| 58 | + |
| 59 | + prop::Integer sLineWidth; // Line width |
| 60 | + prop::Color sLineColor; // Line color |
| 61 | + prop::Color sFillColor; // Fill color |
| 62 | + prop::Integer sPointSize; // Point size |
| 63 | + prop::Color sPointColor; // Point color |
| 64 | + prop::Color sPointHoverColor; // Point hover color |
| 65 | + |
| 66 | + prop::SizeConstraints sConstraints; // Size constraints |
| 67 | + prop::Integer sBorder; // Border size |
| 68 | + prop::Integer sBorderRadius; // Border radius |
| 69 | + prop::Boolean sBorderFlat; // Border is flat |
| 70 | + prop::Color sBorderColor; // Color of the border |
| 71 | + prop::Boolean sGlass; // Draw glass |
| 72 | + prop::Color sGlassColor; // Color of the glass |
| 73 | + prop::Padding sIPadding; // Internal padding |
| 74 | + |
| 75 | + LSP_TK_STYLE_DEF_END |
| 76 | + } |
| 77 | + |
| 78 | + /** |
| 79 | + * Audio envelope: implements audio envelope curve |
| 80 | + */ |
| 81 | + class AudioEnvelope: public Widget |
| 82 | + { |
| 83 | + public: |
| 84 | + static const w_class_t metadata; |
| 85 | + |
| 86 | + public: |
| 87 | + typedef void (*curve_function_t)(float *y, const float *x, size_t count, const AudioEnvelope *sender, void *data); |
| 88 | + |
| 89 | + private: |
| 90 | + friend class AudioSample; |
| 91 | + |
| 92 | + enum point_role_t |
| 93 | + { |
| 94 | + PR_ATTACK, |
| 95 | + PR_HOLD, |
| 96 | + PR_DECAY_BREAK, |
| 97 | + PR_SLOPE_SUSTAIN, |
| 98 | + PR_RELEASE, |
| 99 | + |
| 100 | + PR_TOTAL |
| 101 | + }; |
| 102 | + |
| 103 | + typedef struct point_t |
| 104 | + { |
| 105 | + prop::Float *pX; |
| 106 | + prop::Float *pY; |
| 107 | + prop::Float *pZ; |
| 108 | + prop::StepFloat *pStep; |
| 109 | + ssize_t nX; |
| 110 | + ssize_t nY; |
| 111 | + bool bVisible; |
| 112 | + } point_t; |
| 113 | + |
| 114 | + protected: |
| 115 | + ws::rectangle_t sArea; // The area where the main contents is drawn |
| 116 | + ws::rectangle_t sDrawArea; // The actual draw area used |
| 117 | + point_t vPoints[PR_TOTAL]; // Edit points |
| 118 | + point_t *pHandler; // Current event handler |
| 119 | + size_t nBMask; // Mouse button mask |
| 120 | + ssize_t nLastX; // Last position X |
| 121 | + ssize_t nLastY; // Last position Y |
| 122 | + size_t nPointSize; // Size of point |
| 123 | + bool bQuadPoint; // Quadratic point |
| 124 | + |
| 125 | + prop::Float sAttackTime; // Normalized attack time [0..1] |
| 126 | + prop::Float sAttackCurvature; // Normalized attack slope [0..1] |
| 127 | + prop::StepFloat sAttackStep; // Attack curvature step |
| 128 | + prop::Float sHoldTime; // Normalized Hold time point [0..1] |
| 129 | + prop::Float sDecayTime; // Normalized Decay time point [0..1] |
| 130 | + prop::Float sDecayCurvature; // Normalized Decay slope [0..1] |
| 131 | + prop::StepFloat sDecayStep; // Decay curvature step |
| 132 | + prop::Float sBreakLevel; // Normalized Break level point [0..1] |
| 133 | + prop::Float sSlopeTime; // Normalized Slope time point [0..1] |
| 134 | + prop::Float sSlopeCurvature; // Normalized Slope slope point [0..1] |
| 135 | + prop::StepFloat sSlopeStep; // Slope curvature step |
| 136 | + prop::Float sSustainLevel; // Normalized Sustain level [0..1] |
| 137 | + prop::Float sReleaseTime; // Normalized Release time [0..1] |
| 138 | + prop::Float sReleaseCurvature; // Normalized Release slope [0..1] |
| 139 | + prop::StepFloat sReleaseStep; // Release slope step |
| 140 | + prop::Boolean sHold; // Enable hold time point |
| 141 | + prop::Boolean sBreak; // Enable slope time point |
| 142 | + prop::Boolean sQuadPoint; // Use quad point instead of circle |
| 143 | + prop::Boolean sInvertMouseVScroll; // Invert mouse vertical scroll |
| 144 | + |
| 145 | + prop::Integer sLineWidth; // Line width |
| 146 | + prop::Color sLineColor; // Line color |
| 147 | + prop::Color sFillColor; // Fill color |
| 148 | + prop::Integer sPointSize; // Point size |
| 149 | + prop::Color sPointColor; // Point color |
| 150 | + prop::Color sPointHoverColor; // Point hover color |
| 151 | + |
| 152 | + prop::SizeConstraints sConstraints; // Size constraints |
| 153 | + prop::Color sColor; // Main color of the widget |
| 154 | + prop::Integer sBorder; // Border size |
| 155 | + prop::Integer sBorderRadius; // Border radius |
| 156 | + prop::Boolean sBorderFlat; // Border is flat |
| 157 | + prop::Color sBorderColor; // Color of the border |
| 158 | + prop::Boolean sGlass; // Draw glass |
| 159 | + prop::Color sGlassColor; // Color of the glass |
| 160 | + prop::Padding sIPadding; // Internal padding |
| 161 | + |
| 162 | + ws::ISurface *pGlass; // Surface to draw glass |
| 163 | + |
| 164 | + curve_function_t pFunction; // Curve function |
| 165 | + void *pFuncData; // Curve function supplementary data |
| 166 | + float *vBuffer; // Drawing buffer |
| 167 | + size_t nBufCapacity; // Drawing buffer capacity in floats |
| 168 | + |
| 169 | + protected: |
| 170 | + static status_t slot_on_submit(Widget *sender, void *ptr, void *data); |
| 171 | + |
| 172 | + protected: |
| 173 | + void do_destroy(); |
| 174 | + void drop_glass(); |
| 175 | + void draw_curve(ws::ISurface *surface, float bright, float scaling, const ws::rectangle_t *rect); |
| 176 | + void draw_point(ws::ISurface *s, const lsp::Color & color, const point_t *p); |
| 177 | + void sync_handler(const ws::event_t *e); |
| 178 | + void get_min_area_size(ssize_t *width, ssize_t *height, float scaling); |
| 179 | + point_t *find_point(ssize_t x, ssize_t y); |
| 180 | + float *reserve_buffer(size_t count); |
| 181 | + |
| 182 | + protected: |
| 183 | + virtual void size_request(ws::size_limit_t *r) override; |
| 184 | + virtual void realize(const ws::rectangle_t *r) override; |
| 185 | + virtual void property_changed(Property *prop) override; |
| 186 | + |
| 187 | + public: |
| 188 | + explicit AudioEnvelope(Display *dpy); |
| 189 | + AudioEnvelope(const AudioEnvelope &) = delete; |
| 190 | + AudioEnvelope(AudioEnvelope &&) = delete; |
| 191 | + virtual ~AudioEnvelope() override; |
| 192 | + |
| 193 | + AudioEnvelope & operator = (const AudioEnvelope &) = delete; |
| 194 | + AudioEnvelope & operator = (AudioEnvelope &) = delete; |
| 195 | + |
| 196 | + virtual status_t init() override; |
| 197 | + virtual void destroy() override; |
| 198 | + |
| 199 | + public: |
| 200 | + LSP_TK_PROPERTY(Float, attack_time, &sAttackTime); |
| 201 | + LSP_TK_PROPERTY(Float, attack_curvature, &sAttackCurvature); |
| 202 | + LSP_TK_PROPERTY(StepFloat, attack_step, &sAttackStep); |
| 203 | + LSP_TK_PROPERTY(Float, hold_time, &sHoldTime); |
| 204 | + LSP_TK_PROPERTY(Float, decay_time, &sDecayTime); |
| 205 | + LSP_TK_PROPERTY(Float, decay_curvature, &sDecayCurvature); |
| 206 | + LSP_TK_PROPERTY(StepFloat, decay_step, &sDecayStep); |
| 207 | + LSP_TK_PROPERTY(Float, break_level, &sBreakLevel); |
| 208 | + LSP_TK_PROPERTY(Float, slope_time, &sSlopeTime); |
| 209 | + LSP_TK_PROPERTY(Float, slope_curvature, &sSlopeCurvature); |
| 210 | + LSP_TK_PROPERTY(StepFloat, slope_step, &sSlopeStep); |
| 211 | + LSP_TK_PROPERTY(Float, sustain_level, &sSustainLevel); |
| 212 | + LSP_TK_PROPERTY(Float, release_time, &sReleaseTime); |
| 213 | + LSP_TK_PROPERTY(Float, release_curvature, &sReleaseCurvature); |
| 214 | + LSP_TK_PROPERTY(StepFloat, release_step, &sReleaseStep); |
| 215 | + LSP_TK_PROPERTY(Boolean, hold_enabled, &sHold); |
| 216 | + LSP_TK_PROPERTY(Boolean, break_enabled, &sBreak); |
| 217 | + LSP_TK_PROPERTY(Boolean, quad_point, &sQuadPoint); |
| 218 | + LSP_TK_PROPERTY(Boolean, invert_mouse_vscroll, &sInvertMouseVScroll) |
| 219 | + |
| 220 | + LSP_TK_PROPERTY(Integer, line_width, &sLineWidth); |
| 221 | + LSP_TK_PROPERTY(Color, line_color, &sLineColor); |
| 222 | + LSP_TK_PROPERTY(Color, fill_color, &sFillColor); |
| 223 | + LSP_TK_PROPERTY(Integer, point_size, &sPointSize); |
| 224 | + LSP_TK_PROPERTY(Color, point_color, &sPointColor); |
| 225 | + LSP_TK_PROPERTY(Color, point_hover, &sPointHoverColor); |
| 226 | + |
| 227 | + LSP_TK_PROPERTY(SizeConstraints, constraints, &sConstraints); |
| 228 | + LSP_TK_PROPERTY(Color, color, &sColor); |
| 229 | + LSP_TK_PROPERTY(Integer, border_size, &sBorder); |
| 230 | + LSP_TK_PROPERTY(Integer, border_radius, &sBorderRadius); |
| 231 | + LSP_TK_PROPERTY(Boolean, border_flat, &sBorderFlat); |
| 232 | + LSP_TK_PROPERTY(Color, border_color, &sBorderColor); |
| 233 | + LSP_TK_PROPERTY(Boolean, glass, &sGlass); |
| 234 | + LSP_TK_PROPERTY(Color, glass_color, &sGlassColor); |
| 235 | + LSP_TK_PROPERTY(Padding, ipadding, &sIPadding); |
| 236 | + |
| 237 | + public: |
| 238 | + void set_curve_function(curve_function_t function, void *data = NULL); |
| 239 | + |
| 240 | + public: // ui::IWidget |
| 241 | + virtual void draw(ws::ISurface *s, bool force) override; |
| 242 | + virtual void render(ws::ISurface *s, const ws::rectangle_t *area, bool force) override; |
| 243 | + virtual status_t on_mouse_in(const ws::event_t *e) override; |
| 244 | + virtual status_t on_mouse_out(const ws::event_t *e) override; |
| 245 | + virtual status_t on_mouse_down(const ws::event_t *e) override; |
| 246 | + virtual status_t on_mouse_up(const ws::event_t *e) override; |
| 247 | + virtual status_t on_mouse_move(const ws::event_t *e) override; |
| 248 | + virtual status_t on_mouse_scroll(const ws::event_t *e) override; |
| 249 | + |
| 250 | + public: |
| 251 | + virtual status_t on_submit(); |
| 252 | + }; |
| 253 | + } /* namespace tk */ |
| 254 | +} /* namespace lsp */ |
| 255 | + |
| 256 | + |
| 257 | + |
| 258 | +#endif /* LSP_PLUG_IN_TK_WIDGETS_SPECIFIC_AUDIOENVELOPE_H_ */ |
0 commit comments